我可以指定 EntityTransaction 交易顺序吗?

问题描述

我们在使用 EclipseLink JPA 在 H2 数据库中的单个事务中插入两个表时遇到问题。

数据库架构看起来像…… 表 A {...,IP_ADDRESS Varchar2( 15 ) 不为空 }

表 B {...,IP_ADDRESS Varchar2( 15 ) 不为空, 约束 MY_FK 外键 (IP_ADDRESS) 引用 A
}

我们遇到的问题是 B 上的外键约束使事务失败。

我们正在这样做:

entityManager.getTransaction().begin();

entityManager.merge(保存到一个事务); entityManager.merge(保存到B事务);

entityManager.getTransaction().commit();

看起来 JPA 试图先保存到 B 并且失败了。 或者它可能首先检查 B 上的约束?

无论如何,我们想要做的理想情况就像我多年前回忆的那样,在 oracle 上使用 PL/SQL:

BEGIN
   Do the insert on A;
   Do the insert on B;
   commit;
End;

我认为 Oracle 在事务完成之前不会查看约束。或者因为事务的未提交版本没有违反约束而允许它完成。

有什么想法吗?我查看了文档,但还没有找到任何有用的东西。

谢谢

解决方法

我相信我已经发现了问题,尽管我希望得到比我更了解 JPA 的人的确认。 这里的问题是在代表两个表的实体类中没有定义外键约束。

因此,EntityManager 对两个表之间的关系一无所知,并选择了任意插入顺序。 然后事务失败,因为 JPA 试图在表 A 的行之前插入表 B 的行。

我通过在表 B 和 @OneToMany 关系表 A 中添加一个@ManyToOne 关系来解决这个问题。我将获取类型设置为惰性作为关系定义,因为不需要使用任何获取结果。

在A表实体类中:

// bi-directional one-to-many association to PositionHostPermission
@OneToMany( mappedBy = "the a entity",fetch=FetchType.LAZY )
private Set<B> bInstances;

在表 B 实体类中:

//bi-directional many-to-one association to ipAddress
@ManyToOne( fetch= FetchType.LAZY )
@JoinColumn(name="IP_ADDRESS",insertable=false,updatable=false )
private A aTableInstance;

相关问答

错误1:Request method ‘DELETE‘ not supported 错误还原:...
错误1:启动docker镜像时报错:Error response from daemon:...
错误1:private field ‘xxx‘ is never assigned 按Alt...
报错如下,通过源不能下载,最后警告pip需升级版本 Requirem...