是否有使用@Version的可配置替代方案?

时间:2016-07-15 15:37:14

标签: java hibernate jpa

我在所有JPA域类中都放置了带@Version的注释字段,但这似乎只是额外的锅炉板。有没有办法通过配置解决这个问题?

TIA, 奥莱

1 个答案:

答案 0 :(得分:1)

就JPA规范告诉我们,您无法通过“配置”更改morris.js注释。您可以在程序代码中使用@Version,也可以不使用@Version

参考第3.4.2节(第90页)中的官方JPA specification(最终版本,JPA 2.1),我们发现:

  

如果它具有使用Version映射映射的属性或字段,则会自动启用实体以进行乐观锁定

     

[...]

     

如果只有一些实体包含版本属性,则需要持久性提供程序运行时检查已指定版本属性的实体。对象图一致性无法保证,但某些实体上缺少版本属性不会阻止操作完成。

但是,您可以使用继承的概念,仅通过 abstract 基类在一个位置提供@Version。本课程的编写如下:

@MappedSuperclass
@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
public abstract class AbstractBaseEntity { 

    public static final long INVALID_OBJECT_ID = -42;

    @Version
    private int version;    

    @Id
    @SequenceGenerator(name = "sequence-object", sequenceName = "ID_MASTER_SEQ")
    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "sequence-object")
    @Column(name = "id")
    protected Long objectID = INVALID_OBJECT_ID;

    public final int getVersion() {
        return version;
    }

    @Override
    public long getObjectID() {
        return objectID;
    }

    // ... maybe other methods or fields ...
}

因此,从@Entity继承的所有AbstractPersistentEntity带注释的子类都提供了两个属性:(i)objectID和(ii)version。例如,类SomeClass可以写成:

@Entity
public class SomeClass extends AbstractBaseEntity /*implements SomeInterface*/ {
    // ... specific methods or fields ...
} 

有关使用@MappedSuperclass的详细信息,另请参阅this answer

希望它有所帮助。