我必须处理我无法影响的循环依赖关系,而且我对JPA还不熟悉。
因此,实体拥有相同实体的成员,我通过以下方式解决了这个问题:
@Entity
@Table("A")
public class A {
@ManyToMany
@JoinTable(name = "A_HAS_SUBAS",
joinColumns = {@JoinColumn(name = "A_ID")},
inverseJoinColumns = {@JoinColumn(name = "SUBA_ID")})
private Set<A> as;
}
写入数据库时,我遇到的问题是Hibernate似乎不知道哪个A必须先保留。我尝试通过从A中删除所有关系,写入数据库并在之后通过休眠恢复关系来解决这个问题。
这似乎有效,但如果A
没有SubAs
,这似乎会失败,而这与我对该问题的理解不相符。所以我在某个地方肯定是错的。
没有关系的实体由内部事务持久化:
@Transactional(readOnly = false, propagation = Propagation.REQUIRES_NEW)
private void immediatelySaveNewEntity(A entity) {
try {
if (!dao.entityExistsFromId((int) entity.getId())) { dao.save(entity); }
} catch (Exception e) {
e.printStackTrace();
}
}
结果我得到了一个
ORA-02291:违反了完整性约束(...) - 未找到父密钥
我可以通过删除数据库中的约束来绕过这个问题,但这不是我处理此问题的首选方法。
答案 0 :(得分:0)
我没有在类@Id
中声明任何A
属性。我相信你可能为了简洁而删除了它。
您可以尝试将@ManyToMany
更新为@ManyToMany(cascade=CascadeType.ALL)
,如下所示,然后尝试。
@Entity
@Table("A")
public class A {
@Id
@GeneratedValue(strategy=GenerationType.IDENTITY)
private int id;
@ManyToMany(cascade=CascadeType.ALL)
@JoinTable(name = "A_HAS_SUBAS",
joinColumns = {@JoinColumn(name = "A_ID")},
inverseJoinColumns = {@JoinColumn(name = "SUBA_ID")})
public Set<A> as;
}
能够使用以下hibernate测试代码保存它,并且也可以使用JPA。
Session sess = //Get Session
Transaction tx1 = sess.beginTransaction();
A a = new A();
a.as = new HashSet<>();
a.as.add(new A());
a.as.add(new A());
sess.persist(a);
tx1.commit();
如果我的测试场景错误,发布基本测试场景会有所帮助。
答案 1 :(得分:0)
嗯,这对我来说很有意思,但我的做法还是稍有不妥。
我有循环依赖实体。在写入数据库之前,我删除了实体中的所有关系,将其保存到数据库,然后将更新后的关系恢复。这没关系,因为通过这种方式,我拥有了DB中的所有实体,并且可以轻松地恢复循环依赖关系。 我希望我可以在第一时间摆脱它们,但不是。
错误在我是如何那样做的。通过单个事务,删除关系没有任何效果,因为当具有所有关系的实体最终持久保存到DB时,我已经恢复了之前的状态。 我试图使用新的交易
@Transactional(readOnly = false, propagation = Propagation.REQUIRES_NEW)
但是在同一个Bean中我是如何通过同样的事务学习的。 提示来自Strange behaviour with @Transactional(propagation=Propagation.REQUIRES_NEW)
所以我注入了同一个bean的一个新实例,并在这个实例上执行了新的Transaction,可以访问代理,而且工作正常。