使用"版本"带弹簧靴弹性纤维的文档中的注释

时间:2016-06-03 11:10:15

标签: spring-data-elasticsearch

我使用的是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;
    }
}

1 个答案:

答案 0 :(得分:1)

Spring Data Elasticsearch(从版本2.0.2开始)似乎只对@Version注释提供了部分支持。如果使用版本字段注释文档,则在索引文档时将使用该文档。它将告诉Elasticsearch正在保存的文档是指定的版本。如果新版本小于或等于当前文档的版本,则Elasticsearch将抛出VersionConflictEngineException。

不幸的是,在检索文档时,Spring似乎没有填充此版本字段。据我所知,这使得版本注释无用。也许该项目将在不久的将来增加这种支持。与此同时,我通过扩展Sp​​ring使用的默认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对象中提取其他信息。

使用此代码,如果您获得文档然后尝试将其保存回来,除非您增加版本,否则它将失败。