我這是相當頻繁更新的一類和我使用JPA的樂觀鎖通過:JPA的樂觀鎖定是否知道在Long.MAX_VALUE之後循環爲零?
@Version
public long getVersion() {
return version;
}
我看的價值得到我的測試系統相當大,很緊張生產。 JPA(我正在使用hibernate)處理Long.MAX_VALUE值還是我需要處理自己?
感謝, 本
我這是相當頻繁更新的一類和我使用JPA的樂觀鎖通過:JPA的樂觀鎖定是否知道在Long.MAX_VALUE之後循環爲零?
@Version
public long getVersion() {
return version;
}
我看的價值得到我的測試系統相當大,很緊張生產。 JPA(我正在使用hibernate)處理Long.MAX_VALUE值還是我需要處理自己?
感謝, 本
JPA規範沒有提及,當它到達的版本列的最大值會有怎樣的行爲。我做了一些測試,看看它是如何表現的。
在Java中,Long.MAX_VALUE
相當於:9223372036854775807
我與MySQL的測試我的數據庫。據MySQL documentation,BIGINT
映射到Java的java.util.Long
類型也具有相同的最大值: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
註釋的版本字段。現在,我試着堅持MySQL DB的新的TestEntity
。使用以下代碼:
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();
我手動將version字段設置爲Long的最大值。作爲MySQL數據庫的預期,這是我從我的表有:
1 | test | 9223372036854775807
現在,我更新了TestEntity
代碼。這一次,我用@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的默認循環回到最小值的行爲,一旦達到最大值。
偉大的工作 - 謝謝! – andersonbd1
既然你已經走了這麼遠......你可以嘗試再次更新版本嗎? (想知道它是否處理負數) – andersonbd1
它的確如此。它實際上遞增到-9223372036854775807 – Ish
當前值有多大? –