Spring Data 3.0.5 MongoDB和ElasticSearch Domain Class混合注释

时间:2018-03-15 14:09:57

标签: spring-boot spring-data spring-data-mongodb spring-data-elasticsearch

我正在将我们的应用程序从Spring Boot 1.5.9迁移到2.0.0版本。

在1.5.9版本中,我们已经在多个域类上成功使用了混合注释,例如:

rem_tb.vhd:11:1:@0ms:(assertion note): Result : -1

相同的方法会导致Spring Boot 2.0.0中的probems。当使用MongoDB annotatnion @DBRef 时,Spring会在创建ElasticsearchRepository时抛出异常:

...
@org.springframework.data.mongodb.core.mapping.Document(collection = "folder")
@org.springframework.data.elasticsearch.annotations.Document(indexName = "folder")
public class Folder {
    ...
}

这里有类和confs

的pom.xml

java.lang.IllegalStateException: No association found!

Application.java

   ...
    <properties>
        <java.version>1.8</java.version>
    </properties>

    <parent>
        <groupId>org.springfrsamework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.0.0.RELEASE</version>
    </parent>
    ...
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-mongodb</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-elasticsearch</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-tomcat</artifactId>
        </dependency>

        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.16.18</version>
            <scope>provided</scope>
        </dependency>

    </dependencies>
    ...

Folder.java(请注意@DBRef例外

...
@EnableMongoRepositories("com.hydra.sbmr.repoMongo")
@EnableElasticsearchRepositories("com.hydra.sbmr.repoElastic")
@SpringBootApplication
public class Application extends SpringBootServletInitializer {

    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }

}

Profile.java

package com.hydra.sbmr.model;

import lombok.Getter;
import lombok.Setter;
import org.springframework.data.annotation.Id;
import org.springframework.data.mongodb.core.mapping.DBRef;

@org.springframework.data.mongodb.core.mapping.Document(collection = "folder")
@org.springframework.data.elasticsearch.annotations.Document(indexName = "folder")
public class Folder {

    @Id
    @Getter @Setter private String id;

    // Why MongoDB core mapping @DBRef causes java.lang.IllegalStateException: No association found! exception
    // while ElasticsearchRepository creation???
    @DBRef
    @Getter @Setter private Profile profile;

    @Getter @Setter private String something;

}

FolderElasticRepository.java

package com.hydra.sbmr.model;

import lombok.Getter;
import lombok.Setter;
import org.springframework.data.annotation.Id;

@org.springframework.data.mongodb.core.mapping.Document(collection = "profile")
public class Profile {

    @Id
    @Getter @Setter private String id;

    @Getter @Setter String blah;

}

你可以在GitHub上找到整个迷你项目:https://github.com/hydraesb/sbmr

我的问题:

  • 是否有任何解决方案可以在Spring Boot 2.0.0中使用域类(mongo和弹性)上的混合Annotatnions ???

2 个答案:

答案 0 :(得分:2)

我有同样的问题,发现的解决方案是像这样扩展SimpleElasticsearchMappingContext:

    package com.mypackage;

    import com.fasterxml.jackson.databind.DeserializationFeature;
    import com.fasterxml.jackson.databind.ObjectMapper;
    import org.elasticsearch.client.Client;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.data.elasticsearch.core.ElasticsearchTemplate;
    import org.springframework.data.elasticsearch.core.EntityMapper;
    import org.springframework.data.elasticsearch.core.convert.MappingElasticsearchConverter;
    import org.springframework.http.converter.json.Jackson2ObjectMapperBuilder;

    import java.io.IOException;

    @Configuration
    public class ElasticsearchConfiguration {

        @Bean
        public ElasticsearchTemplate elasticsearchTemplate(Client client, Jackson2ObjectMapperBuilder jackson2ObjectMapperBuilder) {
            return new ElasticsearchTemplate(client, new MappingElasticsearchConverter(new CustomElasticsearchMappingContext()),
                new CustomEntityMapper(jackson2ObjectMapperBuilder.createXmlMapper(false).build()));
        }

        public class CustomEntityMapper implements EntityMapper {

            private ObjectMapper objectMapper;

            public CustomEntityMapper(ObjectMapper objectMapper) {
                this.objectMapper = objectMapper;
                objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
                objectMapper.configure(DeserializationFeature.ACCEPT_SINGLE_VALUE_AS_ARRAY, true);
            }

            @Override
            public String mapToString(Object object) throws IOException {
                return objectMapper.writeValueAsString(object);
            }

            @Override
            public  T mapToObject(String source, Class clazz) throws IOException {
                return objectMapper.readValue(source, clazz);
            }
        }
    }

    package com.mypackage;

    import org.springframework.data.elasticsearch.core.mapping.ElasticsearchPersistentProperty;
    import org.springframework.data.elasticsearch.core.mapping.SimpleElasticsearchMappingContext;
    import org.springframework.data.elasticsearch.core.mapping.SimpleElasticsearchPersistentEntity;
    import org.springframework.data.mapping.model.Property;
    import org.springframework.data.mapping.model.SimpleTypeHolder;

    public class CustomElasticsearchMappingContext extends SimpleElasticsearchMappingContext {
        @Override
        protected ElasticsearchPersistentProperty createPersistentProperty(Property property, SimpleElasticsearchPersistentEntity owner, SimpleTypeHolder simpleTypeHolder) {
            return new CustomElasticsearchPersistentProperty(property, owner, simpleTypeHolder);
        }
    }

    package com.mypackage;

    import org.springframework.data.elasticsearch.core.mapping.ElasticsearchPersistentProperty;
    import org.springframework.data.elasticsearch.core.mapping.SimpleElasticsearchPersistentProperty;
    import org.springframework.data.mapping.PersistentEntity;
    import org.springframework.data.mapping.model.Property;
    import org.springframework.data.mapping.model.SimpleTypeHolder;

    public class CustomElasticsearchPersistentProperty extends SimpleElasticsearchPersistentProperty {

        public CustomElasticsearchPersistentProperty(Property property, PersistentEntity owner, SimpleTypeHolder simpleTypeHolder) {
            super(property, owner, simpleTypeHolder);
        }

        @Override
        public boolean isAssociation() {
            return false;
        }
    }

答案 1 :(得分:0)

我也遇到了这个问题,并通过@ybouraze的解决方案进行了修复

self._clear_thetas()