2011-07-06 52 views
2

我試圖學習使用Hibernate,但可能我不明白@ManyToOne和反向關係。我有兩個實體AuthorDepartment。一個作者有一個部門,一個部門有許多作者。Hibernate @ManyToOne刪除一邊的條目,在許多方面設置FK爲NULL

當我刪除作者時,部門不應該發生任何事情。當我刪除部門時,作者表中的FK應更新爲NULL值(作者不應被刪除)。

我發現nice explanation of inversion和想通了,Author是一個擁有方,並根據this thread當我刪除child(部)的FK應設置爲NULL。但它不會發生,因爲只有部門被刪除,並且FK保留在作者表中(導致org.hibernate.ObjectNotFoundException: No row with the given identifier exists)。

當我在Department實體中添加CascadeType.REMOVE@OneToMany註釋時,所有與部門關聯的作者也被刪除。上述兩種狀態均不可取。我只想刪除Department並將Author表中的FK設置爲​​NULL。怎麼做?

AuthorDepartment實體註釋:提前

回答

2

有某個實體被刪除所有的外鍵設置爲null的沒有自動的方式

@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; 
} 

感謝。你必須明確地得到部門的所有作者,將他們的部門設置爲空,然後刪除部門。

你也可以使用批量更新查詢做到這一點:

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

(因此只有一個查詢,而不是N + 1),但要注意的是,版本字段將不會被更新,不會有任何樂觀的鎖定檢查,並且如果您這樣做,已經加載的會話部門將不會受到影響(在內存中)。

請注意,當您刪除另一個引用的實體時,您不應該有ObjectNotFoundException。相反,您應該在數據庫中啓用外鍵約束,以便在仍有作者引用時刪除部門失敗。這樣,您的數據保持一致狀態。