我使用的是spring-boot-starter-data-elasticsearch(1.4.0.M3)。 我无法使用annoation"版本"获取文档的版本(弹性搜索查询结果中的_version)。 知道为什么注释不起作用吗?
f.e:
@GwtCompatible
@Document(indexName = "myIndexName")
public class Catalog implements Serializable {
private List<GroupProduct> groups;
@Id
private String uuid;
@Version
private Long version;
@Field(type = FieldType.Nested)
private List<Product> products;
private String label;
@NotEmpty
private String organizationUuid;
private List<String> organizationUnitUuids;
private Date updateDate;
private List<VAT> vats;
public Catalog() {
}
public List<GroupProduct> getGroups() {
return groups;
}
public List<Product> getProducts() {
return products;
}
public Date getUpdateDate() {
return updateDate;
}
public void setGroups(List<GroupProduct> groups) {
this.groups = groups;
}
public void setProducts(List<Product> products) {
this.products = products;
}
public void setUpdateDate(Date updateDate) {
this.updateDate = updateDate;
}
public List<VAT> getVats() {
return vats;
}
public void setVats(List<VAT> vats) {
this.vats = vats;
}
public String getUuid() {
return uuid;
}
public void setUuid(String uuid) {
this.uuid = uuid;
}
public String getOrganizationUuid() {
return organizationUuid;
}
public void setOrganizationUuid(String organizationUuid) {
this.organizationUuid = organizationUuid;
}
public String getLabel() {
return label;
}
public void setLabel(String label) {
this.label = label;
}
public List<String> getOrganizationUnitUuids() {
return organizationUnitUuids;
}
public void setOrganizationUnitUuids(List<String> organizationUnitUuids) {
this.organizationUnitUuids = organizationUnitUuids;
}
public Long getVersion() {
return version;
}
public void setVersion(Long version) {
this.version = version;
}
}
答案 0 :(得分:1)
Spring Data Elasticsearch(从版本2.0.2开始)似乎只对@Version
注释提供了部分支持。如果使用版本字段注释文档,则在索引文档时将使用该文档。它将告诉Elasticsearch正在保存的文档是指定的版本。如果新版本小于或等于当前文档的版本,则Elasticsearch将抛出VersionConflictEngineException。
不幸的是,在检索文档时,Spring似乎没有填充此版本字段。据我所知,这使得版本注释无用。也许该项目将在不久的将来增加这种支持。与此同时,我通过扩展Spring使用的默认ResultMapper找到了一种解决方法:
public class ExtendedResultMapper extends DefaultResultMapper {
protected MappingContext<? extends ElasticsearchPersistentEntity<?>, ElasticsearchPersistentProperty> mappingContext;
public ExtendedResultMapper(MappingContext<? extends ElasticsearchPersistentEntity<?>, ElasticsearchPersistentProperty> mappingContext) {
super(mappingContext);
this.mappingContext = mappingContext;
}
@Override
public <T> T mapResult(GetResponse response, Class<T> clazz) {
T result = super.mapResult(response, clazz);
if (result != null) {
setPersistentEntityVersion(result, response.getVersion(), clazz);
}
return result;
}
@Override
public <T> LinkedList<T> mapResults(MultiGetResponse responses, Class<T> clazz) {
LinkedList<T> results = super.mapResults(responses, clazz);
if (results != null) {
for (int i = 0; i < results.size(); i++) {
setPersistentEntityVersion(results.get(i), responses.getResponses()[i].getResponse().getVersion(), clazz);
}
}
return results;
}
private <T> void setPersistentEntityVersion(T result, Long version, Class<T> clazz) {
if (mappingContext != null && clazz.isAnnotationPresent(Document.class)) {
PersistentProperty<ElasticsearchPersistentProperty> versionProperty = mappingContext.getPersistentEntity(clazz).getVersionProperty();
if (versionProperty != null && versionProperty.getType().isAssignableFrom(Long.class)) {
Method setter = versionProperty.getSetter();
if (setter != null) {
try {
setter.invoke(result, version);
} catch (Throwable t) {
t.printStackTrace();
}
}
}
}
}
}
您可以告诉Spring使用此版本而不是默认映射器,如下所示:
@Autowired
private Client client;
@Bean
public ElasticsearchTemplate elasticsearchTemplate() {
MappingElasticsearchConverter converter = new MappingElasticsearchConverter(new SimpleElasticsearchMappingContext());
ExtendedResultMapper mapper = new ExtendedResultMapper(converter.getMappingContext());
return new ElasticsearchTemplate(client, converter, mapper);
}
请注意,仅为Get或Multi-Get请求填充版本。搜索结果不包含版本信息。
您也可以使用相同的方法从GetResponse
对象中提取其他信息。
使用此代码,如果您获得文档然后尝试将其保存回来,除非您增加版本,否则它将失败。