我正在处理一个项目,我们最近将持久性提供程序从使用 OpenJPA 更改为使用 EclipseLink。这是一个大而老的应用程序,我们还从其他进程执行 SQL 插入,这些进程目前暂时无法迁移到 JPA。
我们使用@TableGenerator来引用一个表,我们在其中跟踪要在插入时使用的 id。
当我们使用 OpenJPA 时,我们注意到它首先从表中选择下一个 id,然后更新表以预分配下一个 id。这与旧 SQL 进程获取和预分配下一个 id 的方式完全相同。
当我们切换到 EclipseLink 时,我们注意到了相反的行为,它更新表以预分配下一个 id,然后开始执行插入操作。这导致我们出现java.sql.SQLIntegrityConstraintViolationException,因为最后一个预分配的 id 已被非 JPA 进程用于插入新记录,因此当 JPA 进程到达该 id 时,数据库会给出错误,声称我们正在尝试使用已使用的 id 进行插入。
有没有办法告诉 EclipseLink 以 OpenJPA 的方式处理预分配?
以下是一些来自 OpenJPA 与 EclipseLink 的预分配策略示例,对于这些示例,我将allocationSize设置为 5
OpenJPA
TEST TRACE [main] openjpa.jdbc.SQL - <t 22760146, conn 3658896> executing prepstmnt 9137209 SELECT NEXT_ID FROM ABC.table_ids WHERE TABLE_ID = ? FOR UPDATE [params=(String) 1034] [reused=0]
TEST TRACE [main] openjpa.jdbc.SQL - <t 22760146, conn 3658896> [94 ms] spent
TEST TRACE [main] openjpa.jdbc.SQL - <t 22760146, conn 3658896> executing prepstmnt 23999306 UPDATE ABC.table_ids SET NEXT_ID = ? WHERE TABLE_ID = ? AND NEXT_ID = ? [params=(long) 55, (String) 10, (long) 50] [reused=0]
TEST TRACE [main] openjpa.jdbc.SQL - <t 22760146, conn 3658896> [93 ms] spent
Eclipse链接:
[EL Fine]: 2013-01-23 14:08:35.875--ClientSession(6215763)--Connection(10098848)--Thread(Thread[main,5,main])--UPDATE table_ids SET next_id = next_id + ? WHERE table_id = ?
bind => [5, 10]
[EL Fine]: 2013-01-23 14:08:36.0--ClientSession(6215763)--Connection(10098848)--Thread(Thread[main,5,main])--SELECT next_id FROM table_ids WHERE table_id = ?
bind => [10]
提前致谢!