2015-10-14 45 views
2

我這是相當頻繁更新的一類和我使用JPA的樂觀鎖通過:JPA的樂觀鎖定是否知道在Long.MAX_VALUE之後循環爲零?

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

我看的價值得到我的測試系統相當大,很緊張生產。 JPA(我正在使用hibernate)處理Long.MAX_VALUE值還是我需要處理自己?

感謝, 本

+0

當前值有多大? –

回答

2

JPA規範沒有提及,當它到達的版本列的最大值會有怎樣的行爲。我做了一些測試,看看它是如何表現的。

在Java中,Long.MAX_VALUE相當於:9223372036854775807

我與MySQL的測試我的數據庫。據MySQL documentationBIGINT映射到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的默認循環回到最小值的行爲,一旦達到最大值。

+0

偉大的工作 - 謝謝! – andersonbd1

+0

既然你已經走了這麼遠......你可以嘗試再次更新版本嗎? (想知道它是否處理負數) – andersonbd1

+1

它的確如此。它實際上遞增到-9223372036854775807 – Ish