杰克逊JPA @Version没有序列化

时间:2015-08-05 21:29:57

标签: jackson spring-boot spring-data spring-data-jpa

我的JPA实体如下所示

@Entity
public class OptionsEntity implements Serializable {



    @Id
    @Column(name="OptionNumber",
            nullable=false,
            insertable=true,
            updatable=true,
            length=20)
    private String optionNumber;

    @Basic
    @Column(name="OptionName",
            nullable=false,
            insertable=true,
            updatable=true,
            length=100)
    private String optionName;

    @Basic
    @Column(name="OptionStatusCode",
            nullable=true,
            insertable=true,
            updatable=true,
            length=20)
    private String optionStatusCode;

    @JsonProperty
    @Version
    @Column(name="VersionNumber",
            nullable=false,
            insertable=true,
            updatable=true)
    private Integer versionNumber;

}

我希望versionNumber出现在响应正文中。但是,由于某种原因它被忽略了。

我使用Spring Boot和Spring Data存储库来检索数据。我不确定它是否在这里扮演任何角色。

Spring Data谈到ETags。但是,将Spring Security与Spring Data一起使用似乎是一个复杂的过程(由于缓存标头)以及在客户端(JavaScipt)上使用一组实体时。因此,我想自己处理资源版本控制。

请帮忙。

谢谢!

2 个答案:

答案 0 :(得分:0)

REST具有处理资源状态的专用方法,显式标头以基于该资源状态有条件地触发请求。

所以Spring Data REST的功能是,它将持久存储的方式转换为表达REST的方式。这包括将人工(为了持久存储)引入的属性(标识符,版本属性)转换为REST等价物(自身URI,ETag)。将version属性用作ETag然后需要将其删除两个,原因有多种:

  • 首先是人为引入的,所以实际上不是资源表示的一部分
  • 其目的是通过不同的方式实现的,因此需要“移动”到那些方式
  • 将其保留在表示中会产生ETag中的内容与表示之间不匹配的风险。如果客户端出于某种原因混淆了它们,那么服务器应该如何确定客户端的实际意图呢?

@Version中描述了 Objectname = 'org.apache.activemq:type=Broker,brokerName=localhost' 属性处理的具体细节。

答案 1 :(得分:0)

好的..随着我的理解变得更好......

ETags是一个很酷的功能。特别是因为客户端不必通过JSON模式来获取版本号属性。 ETag应该被普遍认可。

现在,问题在于一组实体。除非我们将集合作为另一个实体来管理,否则我们显然不能在响应上设置ETag。如果存在包含实体集合并且可能将完整对象暴露给客户端的搜索结果的情况,则会出现此问题。

根据SDR的领先优势,似乎没有一种直接的方式来绕过这一点。 PersistentEntityJackson2Module中的下面一段代码是跳过版本ID属性的原因。

            for (BeanPropertyWriter writer : builder.getProperties()) {

            // Skip exported associations
            PersistentProperty<?> persistentProperty = findProperty(writer.getName(), entity, beanDesc);

            if (persistentProperty == null) {
                result.add(writer);
                continue;
            }

            if (associationLinks.isLinkableAssociation(persistentProperty)) {
                continue;
            }

            // Skip ids unless explicitly configured to expose
            if (persistentProperty.isIdProperty() && !configuration.isIdExposedFor(entity.getType())) {
                continue;
            }

            if (persistentProperty.isVersionProperty()) {
                continue; ===> This causes version number to be stripped off.. 
            }

            result.add(writer);
        }

显然我们可以编写自己的替代方案来绕过上面的代码..但那是一些愚蠢的事情......所以我最后做了一些事情,以便其他一切都可以顺利..

@Version
@Column(name="VersionNumber",
        nullable=false,
        insertable=true,
        updatable=true)
private Integer versionNumber;

@JsonProperty(value = "versionNumber")
@Transient
private Integer version;

public Integer getVersion(){
    return (versionNumber != null) ? versionNumber : version;
}

public void setVersion(Integer version){
    if(version != null)
        setVersionNumber(version);
}

public void setVersionNumber(Integer version){
    this.versionNumber = version;
    this.version = version;
}   

我在SDR项目中打开了一个功能请求来处理这种情况DATAREST-636

快乐编码..