【问题标题】:Is there a configurable alternative to using @Version?是否有使用@Version 的可配置替代方案?
【发布时间】:2016-07-15 15:37:13
【问题描述】:

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

TIA, 奥莱

【问题讨论】:

    标签: java hibernate jpa


    【解决方案1】:

    据 JPA 规范告诉我们,您不能通过“配置”更改 @Version 注释。您要么在程序代码中使用@Version,要么不使用。

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

    一个实体会自动启用乐观锁定如果它有一个使用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 ...
    }
    

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

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

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

    希望对你有帮助。

    【讨论】:

    • 太棒了 - 谢谢 - 我正在使用 Spring 的 AbstractPersitable ATM,所以我可能只是对其进行子类化,除非你知道 Spring 中也提供了 version 属性的东西。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-01-26
    • 1970-01-01
    • 2014-01-29
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多