Java 由多个实体拥有的实体

Java 由多个实体拥有的实体,java,jpa,constraints,eclipselink,Java,Jpa,Constraints,Eclipselink,考虑以下关系: 实体A与实体B具有双向一对多关系。 实体A与实体C之间存在单向一对一关系。 实体C与实体D具有双向一对多关系。 实体B与实体D具有双向一对多关系 然后 调用merge psql(引发PostgreSQL异常)时,声明无法插入d,因为b不存在(约束冲突)。 似乎a比c持久化/插入比eclipse链接尝试插入d,而b仍然没有插入。 知道所有这些都必须在同一个事务中发生,如何解决此类问题。您可以尝试合并b,而不是a。实体管理器应该能够从任意点遍历实体树。它不必是“自上而下”。无论如何,

考虑以下关系:

实体A与实体B具有双向一对多关系。 实体A与实体C之间存在单向一对一关系。 实体C与实体D具有双向一对多关系。 实体B与实体D具有双向一对多关系

然后

调用merge psql(引发PostgreSQL异常)时,声明无法插入d,因为b不存在(约束冲突)。 似乎ac持久化/插入比eclipse链接尝试插入d,而b仍然没有插入。
知道所有这些都必须在同一个事务中发生,如何解决此类问题。

您可以尝试合并
b
,而不是
a
。实体管理器应该能够从任意点遍历实体树。它不必是“自上而下”。无论如何,如果您正在创建
a
,那么它不应该是
em.persist
?用于保存a、b的外观有时可能尚未找到a、c、d。merge负责插入和更新。还有一些事情正在发生,正如我所期望的那样,eclipseelink将插入C、A、B,然后是D,除非随后描述的映射不同。是否需要将约束处理延迟到事务之后?启用EclipseLink logging to finest,创建一个没有约束的模式,并查看发出了哪些SQL语句来验证它对所有插入尝试的确切顺序,因为这可能有助于确定遗漏了什么。插入是在一个独立于合并/持久化关系遍历的进程中发出的,并且是在每个类上完成的。因此,应插入所有Cs,然后插入所有As等。您可以尝试合并
b
,而不是
a
。实体管理器应该能够从任意点遍历实体树。它不必是“自上而下”。无论如何,如果您正在创建
a
,那么它不应该是
em.persist
?用于保存a、b的外观有时可能尚未找到a、c、d。merge负责插入和更新。还有一些事情正在发生,正如我所期望的那样,eclipseelink将插入C、A、B,然后是D,除非随后描述的映射不同。是否需要将约束处理延迟到事务之后?启用EclipseLink logging to finest,创建一个没有约束的模式,并查看发出了哪些SQL语句来验证它对所有插入尝试的确切顺序,因为这可能有助于确定遗漏了什么。插入是在一个独立于合并/持久化关系遍历的进程中发出的,并且是在每个类上完成的。因此,应插入所有Cs,然后插入所有As等。您可以尝试合并
b
,而不是
a
。实体管理器应该能够从任意点遍历实体树。它不必是“自上而下”。无论如何,如果您正在创建
a
,那么它不应该是
em.persist
?用于保存a、b的外观有时可能尚未找到a、c、d。merge负责插入和更新。还有一些事情正在发生,正如我所期望的那样,eclipseelink将插入C、A、B,然后是D,除非随后描述的映射不同。是否需要将约束处理延迟到事务之后?启用EclipseLink logging to finest,创建一个没有约束的模式,并查看发出了哪些SQL语句来验证它对所有插入尝试的确切顺序,因为这可能有助于确定遗漏了什么。插入是在一个独立于合并/持久化关系遍历的进程中发出的,并且是在每个类上完成的。因此,应插入所有Cs,然后插入所有As等。
    A a =new A();
    B b =new B();
    C c =new C();
    D d =new D();

    List<B> bs=new ArrayList<>();
    bs.add(b);
    a.setBs(bs);
    b.setA(a);

    a.setC(c);
    List<D> ds=new ArrayList<>();
    ds.add(d);
    b.setDs(ds);
    d.setB(b);

   c.setDs(ds);
   d.setC(c);
em.merge(a);