all-delete-orphanがない!
昨日に引き続きHibernateアノテーションの話題です。
EJB3アノテーションのcascadeにはall-delete-orphanがありません。
これがないと1対多の関係で多のオブジェクトを削除してもDelete文を発行してくれません(それどころかupdateメソッドで落ちます)。
この仕様はマジでいけてない。
これを回避するためにはHibernate独自の@Cascadeアノテーションを使います。
@Cascade(value={CascadeType.ALL, CascadeType.DELETE_ORPHAN})
ここまでは何とかわかったのですが↓の場合うまく削除されません(というか何も変わりませんでした)。
@Entity @Table(name="orders") public class Order { : @OneToMany(fetch=FetchType.EAGER) @Cascade(value={CascadeType.ALL, CascadeType.DELETE_ORPHAN}) <span style="color:red">@JoinColumn(name="order_id")</span> @Index(name="display_position") public List<OrderItem> getOrderItems() { return orderItems; } : }
JoinColumnではなくMappedByを使うとうまくいきました。
@Entity @Table(name="orders") public class Order { : @OneToMany(fetch=FetchType.EAGER, mappedBy="order") @Cascade(value={CascadeType.ALL, CascadeType.DELETE_ORPHAN}) @Index(name="display_position") public List<OrderItem> getOrderItems() { return orderItems; } : }
いまいちよくわからん...。
ということで調べてみると
How can I set inverse="true"?mappedByはinverse="true"と同じってことですね。
The semantic equivalent is mappedBy in the association annotations. Have a look at the reference guide for a complete explaination.
なるほど、他にも
mappedByは、owner側の関連のプロパティの名前を参照する。先ほどの例の場合、これはpassportにあたる。owner側で既に宣言されている為、join columnを宣言する必要はない(してはならない)。mappedBy指定したときはJoinColumn指定しちゃ駄目なんですね。
う〜ん覚えること意外に多いです。