A Day In The Life

とあるプログラマの備忘録

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&lt;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&lt;OrderItem> getOrderItems() {
        return orderItems;
    }
    :
}

いまいちよくわからん...。

ということで調べてみると

How can I set inverse="true"?



The semantic equivalent is mappedBy in the association annotations. Have a look at the reference guide for a complete explaination.
mappedByはinverse="true"と同じってことですね。

なるほど、他にも
mappedByは、owner側の関連のプロパティの名前を参照する。先ほどの例の場合、これはpassportにあたる。owner側で既に宣言されている為、join columnを宣言する必要はない(してはならない)。
mappedBy指定したときはJoinColumn指定しちゃ駄目なんですね。
う〜ん覚えること意外に多いです。