已分离的JPA对象未获取版本字段

时间:2012-02-23 20:28:33

标签: hibernate jpa persistence spring-roo

我正在使用Roo 1.2.1,JPA 2和Hibernate 3.6连接到MSSQL数据库。

我有一个Web服务,它接受JSON并将其解析为一个实体;显然@Version列将为0,因为调用该服务的人对此一无所知。当我第一次调用merge()时它工作正常。该对象被正确保留,并且版本列设置为1.但是下次我使用相同的数据调用Web服务时,它表示该对象是陈旧的,这在技术上是正确的,因为版本始终为0。

他们传递给我们的身份证明是独一无二的,所以我们将其作为我们的主要钥匙。

我想这将由实体经理以某种方式处理。

所以我的问题是:如何在不首先加载数据库中的所有实体,然后更新字段,然后重新保存它们的情况下处理这个问题?这看起来像是一种黑客攻击;也许我会以错误的方式解决这个问题?

我的实体看起来像这样:

@RooJavaBean
@RooToString
@RooJson
@RooJpaActiveRecord(table = "MYTABLE", persistenceUnit = "myPersistenceUnit",
    transactionManager = "myTransactionManager", versionField = "version", identifierColumn = "myIdField")
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
@Entity
public class MyEntity {
  @Id
  @Column(name = "myIdField")
  private long myIdField;

  @Version
  @Column(name = "version")
  private long version;

  @Column("myColumn")
  private String someValue;
}

1 个答案:

答案 0 :(得分:1)

您必须决定是否要进行乐观锁定。

如果要使用客户端发送的内容更新数据库,无论在获取对象的时间与更新对象之间的潜在并发更新,这意味着您不希望乐观锁定,并且不应该不是实体中的版本字段。

如果您想要乐观锁定,那么该版本应该是合并实体的一部分。这就是机制的工作原理:它检查保存的版本号是否与传递的版本号相同。因此,如果你总是传递0,显然,它永远不会起作用。

最简单的方法当然是使其成为发送给客户端和由客户端发送的JSON对象的一部分。您还可以想象在某些内存或数据库表中存储给定实体的版本(发送到客户端以供将来更新,因此密钥将是clientId-entityId),但实现起来会更困难。 / p>