0

私たちはelasticsearchとmysqlで春のブートを持っています。私たちは、elasticsearchへのmysqlからすべてのデータを再インデックスのための機能を持っている、ように簡単である:Springでのレイジーコレクションジャクソンとelasticsearch wihtout jsonignore

@Service 
@Transactional 
public class SearchIndexer { 

    public void reindex(){ 
     elasticsearchRepository.save(jpaRepository.findAll()); 
    } 
} 

今、私たちは「派生」の計算で遅延ロードされたコレクションを持っている請求書と呼ばれるエンティティを、持っています

@Entity 
@Table(name = "invoice") 
@Document(indexName = "invoice") 
public class Invoice implements Serializable { 

    //... other props 

    @OneToMany(fetch = FetchType.LAZY, mappedBy = "invoice") 
    @JsonIgnore 
    private Set<InvoiceItem> invoiceItems = new LinkedHashSet<>(); 

    // getter and setters for invoiceItems 

    public boolean isAllSimple() { 
     if(getInvoiceType()==null){ 
      return false; 
     } 
     if(getInvoiceItems()==null){ 
      return false; 
     } 
     for(InvoiceItem item : getInvoiceItems()){ 
      if(!item.isSimple()){ 
       return false; 
      } 
     } 
     return true; 
    } 
} 

rest-controllerを使用すると、結果のjsonにはプロパティallSimpleが正しく格納されます。これは、1つのトランザクションでhibernate5moduleを使用して実行するためです。

elasticsearchRepository.save(jpaRepository.findAll())(トランザクション内でも)を呼び出すと、elasticsearchのオブジェクトマッパーはLazyInitializationExceptionの "allSimple"プロパティをシリアル化できません。 elasticsearch-objectmapperは、次のように構成されています

@Bean 
public ElasticsearchTemplate elasticsearchTemplate(Client client, Jackson2ObjectMapperBuilder jackson2ObjectMapperBuilder, Hibernate5Module hibernate5Module) {  
    return new ElasticsearchTemplate(client, new CustomEntityMapper(jackson2ObjectMapperBuilder.createXmlMapper(false).modulesToInstall(hibernate5Module).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> T mapToObject(String source, Class<T> clazz) throws IOException { 
     return objectMapper.readValue(source, clazz); 
    } 
} 

hibernate5moduleがロードされ、登録されているが、問題を解決しませんでした。 通常、そのプロパティに "JsonIgnore"を追加しますが、その値が必要なので、これはオプションではありません。 アイデアは何ですか?

答えて

0

私はこれで構成されたプロジェクトを持っていました。

@EnableWebMvc 
@Configuration 
@ComponentScan(basePackages = "com.sagasoftware.tracker.*") 
public class WebConfiguration extends WebMvcConfigurerAdapter { 
    @Bean 
    public MappingJackson2HttpMessageConverter mappingJackson2HttpMessageConverter() { 

     MappingJackson2HttpMessageConverter messageConverter = new MappingJackson2HttpMessageConverter(); 

     ObjectMapper objectMapper = new ObjectMapper(); 
     Hibernate5Module hibernate5Module = new Hibernate5Module(); 

     objectMapper.registerModule(hibernate5Module); 
     objectMapper.configure(FAIL_ON_UNKNOWN_PROPERTIES, false); 
objectMapper.setSerializationInclusion(JsonInclude.Include.NON_EMPTY); 

     messageConverter.setObjectMapper(objectMapper); 

     return messageConverter; 
    } 

    @Override 
    public void configureMessageConverters(List<HttpMessageConverter<?>> converters) { 
     converters.add(mappingJackson2HttpMessageConverter()); 
     super.configureMessageConverters(converters); 
    } 

} 

あなたは豆MappingJackson2HttpMessageConverterを宣言し、あなたの問題を解決する必要がありhibernate5moduleを登録し、春のブートを使用している場合。

私は、残りのコントローラを通してエンティティをレンダリングすることができました。

+0

私はすでにMappingJackson2HttpMessageConverterを持っていますが、これは残りのコントローラに使用されています(これらは問題なく動作しています)... – Indivon

+0

elasticsearchRepositoryを使用して質問を更新してください。 save(jpaRepository.findAll())? –

+0

が更新されました。これは、サービスクラス内の唯一のメソッドであり、残りのエンドポイントによって呼び出されます – Indivon

関連する問題