[英]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.