使用@OneToOne注释从表中删除

时间:2011-01-02 22:55:11

标签: hibernate jpa-2.0 cascade one-to-one

我正在使用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或者是否有更好的解决方案?

4 个答案:

答案 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将起作用。