8

私は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;
}

ここで、トピックにもあるPollオブジェクトを削除すると、エラーが発生します。

java.sql.SQLException:整合性制約違反FKCC42D924982D3F4Bテーブル:ステートメント内のトピック[id =?のポーリングから削除]

別のテーブルに参照がある場合、ポーリングレコードを削除できないためだと理解しています。どうすればこの問題を解決できますか?トピックテーブルでpoll=nullを手動で設定する必要がありますか、それともより良い解決策がありますか?

4

4 に答える 4

6

これは予想される動作です。

双方向の関係に共通する問題は、アプリケーションが関係の一方の側を更新しますが、もう一方の側は更新されず、同期がとれなくなることです。JPAでは、一般的なJavaと同様に、関係を維持するのはアプリケーションまたはオブジェクトモデルの責任です

ソース:オブジェクトの破損、関係の一方の側が更新された後、もう一方の側が更新されない

これを処理する正しい場所は、@PreRemoveコールバックです。

@Entity 
class Poll {

    ...

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

参照:「ONDELETESETNULL」機能を複製するためにJPA/Hibernateを使用する

于 2012-08-24T23:31:51.127 に答える
2

今のところ解決策を見つけることができなかったので、Pollオブジェクトを削除する前に、指定されたプールを含むTopicオブジェクトを常に取得し、それをnullに設定します。

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

そしてそれは正しく動作します。

于 2011-01-04T13:05:23.693 に答える
1

JPA 2の@OneToOneアノテーションにはorphanRemovalフラグが含まれているようです。これを設定して、正常に削除されるかどうかを確認できます。

于 2011-01-03T02:58:51.153 に答える
0

問題は、両側で自動生成IDを使用しているという事実にあります。親エンティティを永続化すると、子エンティティも永続化されますが、親エンティティ内のIDは、データベースから生成されたIDで更新されません。

その結果、子にはIDがないため、親を削除しても子は削除されません。

子エンティティのIDを手動で設定してみてください。そうすれば、orphanRemovalが機能します。

于 2011-12-20T10:32:31.740 に答える