jpa - 如何调整 EclipseLink 预分配策略

标签 jpa eclipselink openjpa allocation

我正在从事一个项目,我们最近将我们的持久性提供程序从使用 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]

提前致谢!

最佳答案

问题不在于更新与选择的顺序,而在于对是否具有当前值的解释。 EclipseLink 假定它获得了当前值,而 OpenJPA 似乎没有。

理想情况下,您可以更改非 JPA 用法以做出相同的假设。如果不能,您可以在 EclipseLink 中编写自己的自定义序列对象。

为此,创建 TableSequence 的子类并覆盖 buildSelectQuery() 方法以向 SQL 添加“+ 1”(或“- 1”)以说明假设的差异。

然后您可以使用 SessionCustomizer 添加自定义序列。

另请在 EclipseLink 中记录错误,以便为 OpenJPA 排序添加兼容性选项。

关于jpa - 如何调整 EclipseLink 预分配策略,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14591723/

相关文章:

java - JPA实体没有表中的列,但根据实体中不存在的列进行查询

jpa - JPA 标准 API 和多个子查询的问题

java - Eclipselink 持久性转换器未调用

java - 我的 JPA DAO 有什么问题?它会持续存在,但合并时出错

java - JPA如何推断属性的数据类型

java - 使用 Multi-Tenancy 架构更新所有模式

java - 失败后重置 Eclipselink JPA 实体管理器

jpa - Eclipselink OptimisticLock 导致死锁

java - JPA 实体的集合成员分离或不受管理

hibernate - 使用 JPA 进行哈希分区/分片的库