簡體   English   中英

JPA / MySql具有遞增的主要和次要ID的特權

[英]JPA/MySql An eniity with incremental primary and secondary id

我有資源,比如說一本書。 我希望這本書具有書號和版本號

在創建操作上,我想要增量ID

book id     version id   status
1             0          ACTIVE
2             0          ACTIVE
3             0          ACTIVE

更新時,我想擁有相同ID的新版本

book id     version id   status
    1             0          INACTIVE    //Changed to inactive
    1             1          ACTIVE      //new row with same id
    2             0          ACTIVE
    3             0          ACTIVE

我有兩個桌子可以達到這個目的

生成ID的表

  CREATE TABLE `BookIdGenerator` (
`id`int(11) NOT NULL AUTO_INCREMENT ,
PRIMARY KEY (`id`)
)ENGINE=InnoDB DEFAULT CHARSET=utf8;

書桌

 CREATE TABLE `Book` (
         `id` int(11) NOT NULL ,
         `version` int(11) NOT NULL,
         `title` varchar(255) NOT NULL,
         `isbn` varchar(255) NOT NULL,

     PRIMARY KEY (`id`,`version`),
     foreign key (`id`) references BookIdGenerator(`id`)
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8;

實體類是

class Book{
private long id;
private int version;
//other fields

要達到此目的,正確的表結構JPA注釋是什么?

沒有任何單獨的表,我可以在id和version處使用@Id,但這不允許在持久存儲時檢索分配給對象的ID。

更新:我可以有一個Emeddable BookId類(具有書ID和版本),並且可以在Book中使用@EmbeddedId,但是我必須編寫一個ID生成器來生成ID。 我該怎么辦,這樣在堅持使用create方法之前不必寫一個生成器來分配id?

JPA @版本

版本列的預期用途與JPA中的預期用途不同。

版本字段用於支持單個數據庫記錄的樂觀鎖定。 每次事務嘗試更新記錄時,都會將版本字段與數據庫中的值進行比較。 如果它們相同,則沒有其他事務更新記錄。 記錄將被更新,版本列將被更改。 如果它們不相同,則其他事務更新記錄,並且將引發OptimisticLockException。

在更新實體(使用JPA的merge())時,JPA更新現有記錄。

在您的問題中,當您“更新”記錄時,實際上是在創建(持久)新記錄。

此外,版本字段由JPA管理,應用程序不應觸摸-只讀。 在您的示例中,您正在使用指定的版本號創建新記錄。

主鍵

您已經為Book定義了PrimaryKey,但是,您需要多個記錄來保存相同的PrimaryKey。 這將失敗,因為PrimaryKey必須是唯一的。

在這種情況下,您的ID和版本構成一個復合主鍵,您需要將這些字段分離到一個單獨的類中; 主鍵類

如果您確實想將每個更改記錄為一條記錄作為單獨的記錄,則需要特定於應用程序的版本控制,因為您不能出於目的使用JPA版本字段。

Book_id     Book_Update_id   status    JPA_Version
    1             0          INACTIVE       0
    1             1          ACTIVE         0
    2             0          ACTIVE         0
    3             0          ACTIVE         0 

我保留了“ JPA版本”列,但是如果您不修改記錄,則不需要這樣做。

因此您的書將看起來像這樣。

@Entity //Tell JPA this is an entity to be mapped to your DB.
@IdClass(BookId.class) //you need to repeat the PK fields in this class
class Book{
@Id @Column(name=”Book_id”) //Both id and bookUpdateId annotated with @ID
private long id;            //Together they for a compound Primary Key
@Id @Column(name=”Book_Update_id”)
String bookUpdateId
@Version @Column(name=”JPA_Version”) //Tell JPA where to record its version info
private int version;

在創建新記錄時,由應用程序決定是否要根據記錄的現有值確定id和bookUpdateId值。 JPA無法知道這一點。 因此,不需要單獨的表來支持ID生成。

有關所有這些主題,請參見Mike Keith和Merrick Schincariol撰寫的Pro JPA 2,一個很好的介紹及其他內容。 這也將詳細解釋@IdClass。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM