gpt4 book ai didi

java - JPA/MySql 具有递增主次id的eniity

转载 作者:行者123 更新时间:2023-11-30 22:38:47 24 4
gpt4 key购买 nike

我有一个资源,比如说一本书。我希望这本书有书号和版本号

在创建操作时我想要增量 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;

书 table

 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。我该怎么做才能在坚持创建方法之前不必编写生成器来分配 id?

最佳答案

JPA @Version

您对版本列的预期用途与 JPA 中的预期不同。

版本字段用于支持单个数据库记录的乐观锁定。每次事务尝试更新记录时,都会将版本字段与数据库中的值进行比较。如果它们相同,则没有其他事务更新记录。将更新记录并更改版本列。如果它们不相同,那么一些其他事务已经更新了记录并且将抛出 OptimisticLockException。

更新实体时(使用 JPA 的 merge()),JPA 更新现有记录。

在您的问题中,当您“更新”图书记录时,您实际上是在创建(保留)一条新记录。

此外,版本字段由 JPA 管理,不应被应用程序触及 - 只读。在您的示例中,您正在使用不允许的指定版本号创建新记录。

主键

您为 Book 定义了一个 PrimaryKey,但是,您需要多个记录来保存相同的 PrimaryKey。这将失败,因为 PrimaryKey 必须是唯一的。

在这种情况下,您的 id 和 version 形成一个复合主键,您需要将这些字段分离到一个单独的类中;一个主键类

如果您真的想将对记录的每个更改记录为单独的记录,则需要特定于应用程序的版本控制,因为您不能将 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。

关于java - JPA/MySql 具有递增主次id的eniity,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31663078/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com