开发者

Deleting from table with @OneToOne annotation

开发者 https://www.devze.com 2023-02-02 17:50 出处:网络
I\'m using JPA2 and Hibernate implementation. I\'ve got simple mapping like this: @Entity class Topic {

I'm using JPA2 and Hibernate implementation.

I've got simple mapping like this:

@Entity 
class Topic {

    @开发者_Python百科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;
}

Now, when I delete a Poll object which is also in Topic I get an error.

java.sql.SQLException: Integrity constraint violation FKCC42D924982D3F4B table: TOPICS in statement [delete from polls where id=?]

I understand that it is because I can't delete the Poll record if it has references in another table. How can I solve this problem? Do I have to manually set poll = null in a Topic table or is there a better solution?


This is expected behavior:

A common problem with bi-directional relationships is the application updates one side of the relationship, but the other side does not get updated, and becomes out of sync. In JPA, as in Java in general it is the responsibility of the application, or the object model to maintain relationships.

Source: Object corruption, one side of the relationship is not updated after updating the other side

The correct place to handle this is in a @PreRemove callback:

@Entity 
class Poll {

    ...

    @PreRemove
    private void preRemove() {
        Poll poll = topic.getPoll();
        topic.setPoll( null );
    }
}

See also: Have JPA/Hibernate to replicate the “ON DELETE SET NULL” functionality


I was not able to find a solution by now, so before I delete a Poll object I always get a Topic object which contains given Pool and set it to null.

Topic topic = entityManager.find( Topic.class, 1 );
Poll poll = topic.getPoll();
topic.setPoll( null );
entityManager.remove( poll );

And it works correctly.


It looks like the @OneToOne annotation in JPA 2 contains an orphanRemoval flag, you could try setting that and see if it removes it gracefully.


The problem lies in the fact that you are using Auto-Generated ID on both sides. When you persist the parent entity, the child entity is persisted as well but its ID inside the parent entity is not updated with the one generated from the database.

As a result, when you delete the parent, you won't delete the child, because the child has no ID.

Try setting manually the ID of the child entity and orphanRemoval will work.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号