Java JPA(EclipseLink)如何在持久化实际实体之前接收下一个 GeneratedValue?
Posted
技术标签:
【中文标题】Java JPA(EclipseLink)如何在持久化实际实体之前接收下一个 GeneratedValue?【英文标题】:Java JPA (EclipseLink) How to receive the next GeneratedValue before persisting actual entity? 【发布时间】:2011-09-30 08:11:12 【问题描述】:我正在使用 JPA 的 EclipseLink 实现,但遇到了问题。
这是我的实体类:
@实体 @Table(name = "出席人数") 公共类出勤实现可序列化 私有静态最终长序列版本UID = 1L; @ID @GeneratedValue(策略 = GenerationType.IDENTITY) @基本(可选=假) @Column(name = "id") 私人短 id;....
在我的 mysql 表(即底层数据存储)中,我还设置了 auto_increment
标志。
如何在持久化实体之前获取自动生成的值(id
字段)? 所以如果表中有 3 个实体(id IN (1, 2, 3)
),我想获取 4 个作为下一个自动生成的值。
我唯一的解决方法是:
-
获取
id
字段最大的实体的id。
我能做的就这么多吗?
【问题讨论】:
你为什么要这样做? @Nizet 我有一个用于创建出勤的对话框,我希望用户知道即将创建的出勤的 ID。据说这不是 100% 需要的。 @JB Nizet:确实是一个非常有效的问题。 【参考方案1】:如果使用 JPA 2.0,您可以试试这个,
entityManagerFactory.getPersistenceUnitUtil().getIdentifier(attendance);
免责声明: 自己从未尝试过。
否则,您可以将您的 id 生成策略更改为可以在持久化实体之前获得id
的东西。例如,尝试使用表生成器来生成您的id
s。在这里,我找到了一个例子,Use Table Generator To Generate ID。然后,您将能够直接从该表中读取值。您可能无法使用@Id
自动处理此问题,确切地说,您最终将自己计算下一个id
。因此,您可以采用相同的想法,但自己完成所有工作并在创建操作时设置id
,并且不要让 JPA 生成一个。
或者,如果支持,您可能想使用sequence
。在sequence
的情况下,您还需要自己获取下一个值并手动设置。准备好在没有插入的情况下放弃跳过的id
s,或者以某种方式处理。
或者你对你正在做的事情很好。只需注意原子性。或者您可能不会遇到多个事务同时运行的情况。
【讨论】:
getIdentifier 调用不起作用。该方法的文档说:“返回实体的 id。在数据库插入发生之前,生成的 id 不能保证可用。如果实体还没有 id,则返回 null。” @JB Nizet:那么我应该使用表格生成器吗? @JB Nizet:是的,我也不能保证。我的意思是,正如我所说,我从未尝试过。顺便说一句,不能保证也可以推断它可能有效。无论如何,我也给出了第二个建议,OP可能会考虑。 @Daniel:是的,无论如何。但是尝试一次不会有任何伤害。很简单,你看。 @Daniel:不。 TableGenerator 在持久化之前不会让您知道 ID,因为它是持久化调用生成器来获取 ID。您必须自己分配 ID。以上是关于Java JPA(EclipseLink)如何在持久化实际实体之前接收下一个 GeneratedValue?的主要内容,如果未能解决你的问题,请参考以下文章
JPA + EclipseLink+ HSQLDB 不创建表
JPA 使用指南 /Eclipselink/JPA 实体生成器
JPA + EclipseLink + SAP云平台 = 运行在云端的数据库应用
JPA + EclipseLink + SAP云平台 = 运行在云端的数据库应用