我正在使用JPA2和Hibernate实现。
我有这样的简单映射:
@Entity
class Topic {
@Id
@GeneratedValue(strategy = IDENTITY)
int id;
@OneToOne(cascade = ALL)
@JoinColumn(name = "id_poll")
private Poll poll;
}
@Entity
class Poll {
@Id
@GeneratedValue(strategy = IDENTITY)
int id;
}
现在,当我删除一个也在Topic中的Poll对象时,我收到一个错误。
java.sql.SQLException:完整性约束违规FKCC42D924982D3F4B表:声明中的TOPICS [从民意调查中删除id =?]
据我所知,这是因为如果Poll记录在另一个表中有引用,我就无法删除它。我怎么解决这个问题?我是否必须在主题表中手动设置poll = null或者是否有更好的解决方案?
答案 0 :(得分:6)
这是预期的行为:
双向关系的一个常见问题是应用程序 更新关系的一方,但另一方没有得到 更新,并变得不同步。在JPA中,就像在Java中一般一样 应用程序的责任,或维护对象模型 关系强>
来源:Object corruption, one side of the relationship is not updated after updating the other side
处理此问题的正确位置是@PreRemove回调:
@Entity
class Poll {
...
@PreRemove
private void preRemove() {
Poll poll = topic.getPoll();
topic.setPoll( null );
}
}
另请参阅:Have JPA/Hibernate to replicate the “ON DELETE SET NULL” functionality
答案 1 :(得分:1)
看起来JPA 2中的@OneToOne注释包含一个orphanRemoval标志,您可以尝试设置它并查看它是否正常删除它。
答案 2 :(得分:1)
我现在无法找到解决方案,所以在删除Poll对象之前,我总是得到一个包含给定Pool的Topic对象并将其设置为null。
Topic topic = entityManager.find( Topic.class, 1 );
Poll poll = topic.getPoll();
topic.setPoll( null );
entityManager.remove( poll );
它运作正常。
答案 3 :(得分:0)
问题在于您在两侧都使用自动生成ID。当您持久保存父实体时,子实体也会被持久化,但它在父实体中的ID不会使用从数据库生成的ID更新。
因此,当您删除父级时,您不会删除该子级,因为该子级没有ID。
尝试手动设置子实体的ID,并且orphanRemoval将起作用。