【发布时间】:2016-07-15 15:37:13
【问题描述】:
我在我的所有 JPA 域类中都放置了一个带有 @Version 的注释字段,但这似乎是额外的样板。有没有办法通过配置解决这个问题?
TIA, 奥莱
【问题讨论】:
我在我的所有 JPA 域类中都放置了一个带有 @Version 的注释字段,但这似乎是额外的样板。有没有办法通过配置解决这个问题?
TIA, 奥莱
【问题讨论】:
据 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。
希望对你有帮助。
【讨论】: