2

私は Hibernate で作業することを学ぼうとしていますが、おそらく私は@ManyToOne逆の関係を理解し​​ていません。と の 2 つのエンティティがAuthorありDepartmentます。1 人の著者には 1 つの部門があり、1 つの部門には複数の著者がいます。

Author を削除しても、Department には何も起こらないはずです。Department を削除すると、Author のテーブルの FK がNULL値に更新されます (Author は削除されません)。

私は反転の素晴らしい説明を見つけ、それAuthorが所有側であることがわかりました。このスレッドによると、子 (部門) を削除すると、FK を に設定する必要がありますNULL。しかし、Department だけが削除され、FK が Author テーブルに残っているため (これが につながります)、それは起こりませんorg.hibernate.ObjectNotFoundException: No row with the given identifier exists

エンティティの注釈に追加CascadeType.REMOVEすると、部門に関連付けられているすべての作成者も削除されます。前述の状態はどちらも望ましくありません。Department を削除し、Author テーブルの FK を に設定したいだけです。どうやってするか?@OneToManyDepartmentNULL

AuthorおよびDepartment注釈付きのエンティティ:

@Entity
@Table(name = "author")
public class Author implements Serializable {

    @Id
    @Column(name = "idauthor")
    @GeneratedValue
    private Integer idAuthor;

    @DepartmentFormat
    @ManyToOne
    @JoinColumn(name = "department", nullable = true)
    private Department department;
}

@Entity
@Table(name="department")
public class Department implements Serializable {

    @Id
    @Column(name="iddepartment")
    @GeneratedValue
    private Integer iddepartment;

    @OneToMany(mappedBy = "department", cascade = {CascadeType.PERSIST, CascadeType.MERGE, CascadeType.REFRESH})
    private Set<Author> authors;
}

前もって感謝します

4

1 に答える 1

2

null一部のエンティティが削除されたときにすべての外部キーを自動的に設定する方法はありません。部門のすべての作成者を明示的に取得し、その部門を null に設定してから、部門を削除する必要があります。

これを行うには、一括更新クエリを使用することもできます。

update Author a set a.department = null where a.department = :department

(したがって、n + 1 ではなく 1 つのクエリしかありません)。ただし、バージョン フィールドは更新されず、楽観的ロック チェックは行われず、セッションの既に読み込まれた部門は更新されないことに注意してください。そうする場合、(メモリ内で)影響を受けます。

別のエンティティから参照されているエンティティを削除する場合は、ObjectNotFoundException が発生しないように注意してください。代わりに、データベースで外部キー制約を有効にして、部門を参照している作成者がまだいる場合に部門の削除が失敗するようにする必要があります。そうすれば、データは一貫した状態に保たれます。

于 2011-07-06T13:12:26.287 に答える