【发布时间】:2018-01-31 17:13:27
【问题描述】:
我们有带有 elasticsearch 和 mysql 的 spring boot。我们有一个功能可以将 mysql 中的所有数据重新索引到 elasticsearch 中,这很简单:
@Service
@Transactional
public class SearchIndexer {
public void reindex(){
elasticsearchRepository.save(jpaRepository.findAll());
}
}
现在我们有一个名为 invoice 的实体,它有一个带有“派生”计算的延迟加载集合:
@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”。这是因为我们在一个事务中使用 hibernate5module 运行它。
但是,当我们调用elasticsearchRepository.save(jpaRepository.findAll())(也在事务中)时,elasticsearch 的对象映射器无法序列化“allSimple”属性,因为LazyInitializationException。 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”,但我们需要该值,所以这不是选项。 有什么想法吗?!
【问题讨论】:
标签: json spring hibernate spring-data-jpa spring-data-elasticsearch