Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/database/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 如何正确实现JPA中相关实体的乐观锁定_Java_Database_Hibernate_Jpa_Locking - Fatal编程技术网

Java 如何正确实现JPA中相关实体的乐观锁定

Java 如何正确实现JPA中相关实体的乐观锁定,java,database,hibernate,jpa,locking,Java,Database,Hibernate,Jpa,Locking,以下是我的数据模型的简化版本: @Entity @Table(name = "DATA_TABLE") public class DataTable implements Serializable { @Id @Column(name = "DATA_TABLE_ID") private int dataTableId; @Column(name = "TITLE") private String title; @OneToMany(mappe

以下是我的数据模型的简化版本:

@Entity
@Table(name = "DATA_TABLE")
public class DataTable implements Serializable {
    @Id
    @Column(name = "DATA_TABLE_ID")
    private int dataTableId;

    @Column(name = "TITLE")
    private String title;

    @OneToMany(mappedBy = "dataTableId", cascade = CascadeType.ALL, orphanRemoval = true)
    private Set<Row> rows;

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

@Entity
@Table(name = "ROW")
public class Row implements Serializable {
    @Id
    @Column(name = "ROW_ID")
    private int rowId;

    @ManyToOne
    @JoinColumn(name = "DATA_TABLE_ID")
    private DataTable dataTable;

    @OneToMany(mappedBy = "dataTableId", cascade = CascadeType.ALL, orphanRemoval = true)
    private Set<Row> rows;
}

@Entity
@Table(name = "CELL")
public class Cell implements Serializable {
    @Id
    @Column(name = "CELL_ID")
    private int cellId;

    @ManyToOne
    @JoinColumn(name = "ROW_ID")
    private Row row;

    @Column(name = "TEXT")
    private String text;
}
@实体
@表(name=“数据表”)
公共类DataTable实现了可序列化{
@身份证
@列(name=“数据表ID”)
私有int-dataTableId;
@列(name=“TITLE”)
私有字符串标题;
@OneToMany(mappedBy=“dataTableId”,cascade=CascadeType.ALL,orphanRemoving=true)
私有集行;
@版本
@列(name=“VERSION”)
私人长版;
}
@实体
@表(name=“ROW”)
公共类行实现可序列化{
@身份证
@列(name=“ROW\u ID”)
私有内部rowId;
@许多酮
@JoinColumn(name=“数据表ID”)
私有数据表;
@OneToMany(mappedBy=“dataTableId”,cascade=CascadeType.ALL,orphanRemoving=true)
私有集行;
}
@实体
@表(name=“CELL”)
公共类单元格实现可序列化{
@身份证
@列(name=“CELL\u ID”)
私人内特细胞;
@许多酮
@JoinColumn(name=“ROW\u ID”)
私人行;
@列(name=“TEXT”)
私有字符串文本;
}
我需要为与现有系统兼容的模型实现乐观锁定。 在其中,数据表中的版本被发送给服务的用户,用户必须将其与执行的acion一起发送回,这用于验证在此期间没有任何更改。每当属于特定数据表的行或单元格发生更改时,版本字段就会更新

不幸的是,这似乎不适用于JPA@Version注释(Hibernate 4.1.9)。当
数据表
表中保存的属性发生更改时,
版本
字段将更新,例如
标题
,但更改/添加行和单元格不会增加
版本


在JPA中,是否有任何方法可以通过@Version或其他机制(expicit锁定?)来实现此功能,以防止并发错误,例如

我认为这是因为您要映射到的字段是基本类型(
long
)。您应该改用包装类型
Long

JPA为每个实体对象维护一个版本号。新实体对象的初始版本(首次存储在数据库中时)为1。在修改实体对象的每个事务中,其版本号自动增加一个。版本号在内部管理,但可以通过定义版本字段来公开

在提交(和刷新)期间,JPA检查必须更新或删除的每个数据库对象,并将数据库中该对象的版本号与正在更新的内存中对象的版本号进行比较。如果版本号不匹配,事务将失败,并引发OptimisticLockException,这表明自当前更新程序检索该对象以来,该对象已被其他用户(使用其他EntityManager)修改


仅当行发生更改时,才会发生此行为。。外键无关紧要,因此版本号不会增加。

是否希望在所有表中应用@version?如果通过数据库GUI向表中添加更多行或更多列,@Version将不会更改。是否解决了此问题?如果是,您是如何解决的?谢谢您的解释。问题是我真正需要的是考虑对与该版本实体相关的所有实体所做的所有更改。也许您可以使用悲观锁并设置一个技术列来处理自定义行为。这没有帮助。对不起,我没说清楚。
@Version
乐观锁定工作正常,即当我尝试提交的实体上存在错误的版本号时,将引发OptimisticLockException。但是,当一个相关实体(由具有
@version
注释的实体所有)发生更改时,此版本不会增加。