JPA 的乐观锁定是否知道在 Long.MAX_VALUE 之后循环到零?



我有一个经常更新的类,我正在使用JPA的乐观锁定:

  @Version
  public long getVersion() {
    return version;
  }

在我的测试系统上,我看到这个值变得相当大,我对生产感到紧张。JPA(我使用hibernate)处理跨长。MAX_VALUE值还是我需要自己处理?

谢谢,本

JPA规范没有提到当它达到版本列的最大值时将会发生什么行为。我做了一些测试来看看它的行为。

在Java中,Long.MAX_VALUE相当于:9223372036854775807

我测试MySQL作为我的数据库。根据MySQL文档,映射到Java的java.util.Long类型的BIGINT也具有相同的最大值:9223372036854775807

在Java中,当您增加Long.MAX_VALUE并打印结果时,您将得到-9223372036854775808,它相当于Long.MIN_VALUE。所以我们可以说,一旦Java超过了最大值,它就会循环回到最小值。MySQL的BIGINT的最小值也与Java的相同:-9223372036854775808

所以这里是我如何使用JPA测试:

我最初用ff创建了一个TestEntity。代码:

@Entity
public class TestEntity implements Serializable {
    @Id
    @GeneratedValue(strategy=GenerationType.IDENTITY)
    private Integer id;
    private Long version;
    private String name;
    ...
} 

注意,我首先没有用@Version注释版本字段,所以我可以手动设置为Long的最大值。现在,我尝试将新的TestEntity持久化到MySQL DB。使用以下代码:

em.getTransaction().begin();    
TestEntity test = new TestEntity();
test.setName("test");
test.setVersion(Long.MAX_VALUE); // manually set the version to the maximum value
em.persist(test);
em.getTransaction().commit();

我手动将版本字段设置为Long的最大值。在MySQL数据库中,下面是我从表中得到的结果:

1 | test | 9223372036854775807

现在,我更新了TestEntity代码。这一次,我用@Version注释了version字段。

@ entity公共类TestEntity实现Serializable {

@Id
@GeneratedValue(strategy=GenerationType.IDENTITY)
private Integer id;
@Version
private Long version;
private String name;
...

}

然后,我创建了一个新代码来查找之前创建的TestEntity并更新其名称:
em.getTransaction().begin();
TestEntity testEntity = em.find(TestEntity.class, 1);
testEntity.setName("changed");
em.getTransaction().commit();

令人惊讶的是,我没有得到一个错误,说我已经达到最大值。相反,实体已成功更新。下面是我的表格:

1 | changed | -9223372036854775808

你看,它确实循环回到最小值。我假设JPA目前没有阻止达到最大值的机制。它实际上只是使用Java的默认行为,即在达到最大值时循环回到最小值。

相关内容

最新更新