2017-06-09 37 views
2

執行我有兩個實體:ID變成「?」當CrudRepository

@Entity 
@Table(name="\"Group\"") 
public class Group implements Serializable { 

    @Id 
    @GeneratedValue(strategy = GenerationType.IDENTITY) 
    @Column(name="id") 
    private long id; 

    @NotNull 
    @ManyToOne(cascade=CascadeType.REMOVE, fetch=FetchType.EAGER) 
    @JoinColumn(name="admin_id", referencedColumnName="id") 
    private User admin; 
    // .. other properties + setters and getters 

} 

-

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

    @Id 
    @GeneratedValue(strategy = GenerationType.IDENTITY) 
    @Column(name="id") 
    private long id; 

    @OneToMany(cascade = CascadeType.REMOVE, fetch=FetchType.EAGER, mappedBy="admin") 
    private Set<Group> ownedGroups; 
    // other properties + setters and getters 
} 

這對於擴展CrudRepositoryGroup實體庫:

public interface GroupRepository extends CrudRepository<Group, Long> { 
    public Group findById(long id); 
} 

當我刪除組,數據庫中的所有組都會被刪除。爲什麼會發生?

這是我在日誌中看到(我在我的組表作爲日誌行數相同數量的條目)

Hibernate: delete from `group` where id=? 
Hibernate: delete from `group` where id=? 
Hibernate: delete from `group` where id=? 
Hibernate: delete from `group` where id=? 
Hibernate: delete from `group` where id=? 
Hibernate: delete from `group` where id=? 

我敢肯定,我通過正確的ID來組信息庫的.delete方法。

+0

但爲什麼調用'groupRepository.delete(id)'刪除表中的所有項目? –

+0

你可以設置show_sql在休眠配置和顯示日誌,你看到什麼時候刪除 – xyz

+0

'休眠:從'組''刪除其中id =?' 我把代碼中斷點,我敢肯定,傳入組ID不是'null'或格式不正確。 –

回答

1

看看在你的代碼下面幾行:

@ManyToOne(cascade=CascadeType.REMOVE, fetch=FetchType.EAGER) 
@JoinColumn(name="admin_id", referencedColumnName="id") 
private User admin; 

這些以及:

@OneToMany(cascade = CascadeType.REMOVE, fetch=FetchType.EAGER, mappedBy="admin") 
private Set<Group> ownedGroups; 

從我看到我可以假設,刪除組時,您還刪除管理員該組。而且,由於您刪除了管理員 - 您還刪除了管理員擁有的所有組。

這是因爲您以錯誤的方式使用CascadeType.REMOVE。刪除組時,此註釋會導致多米諾骨牌效應。您可以在這裏閱讀有關Hibernate中的級聯的文章https://docs.oracle.com/cd/E19798-01/821-1841/bnbqm/index.html

我建議你刪除CascadeType.REMOVE,因爲它似乎不適合你的域模型非常好。 通常,當您的實體之間存在較強的組合關係時,這種類型的級聯非常有用,其中子實體在沒有父級的情況下沒有任何意義。例如公司和地址。如果您將公司移除,將其地址存儲在數據庫中沒有任何意義。你的情況是實體聚合而不是組合。您的子實體(管理員)可以在沒有其父實體(組)的情況下存在。這同樣適用於用戶和擁有的組 - 如果您刪除了該組的所有者,則可能無法刪除所有擁有的組(例如,因爲某些人將來可能擁有該組)。

2

您在日誌中看到Hibernate: delete fromwhere id=?,因爲這是hibernate默認記錄查詢的方式。如果你想看到的參數綁定到查詢,增加以下包 log4j.logger.org.hibernate.type=tracehere's some more info on this

至於去除所有羣體問題的日誌記錄級別,這是由

@OneToMany(cascade = CascadeType.REMOVE, fetch=FetchType.EAGER, mappedBy="admin") 
private Set<Group> ownedGroups; 

@ManyToOne(cascade=CascadeType.REMOVE, fetch=FetchType.EAGER) 
@JoinColumn(name="admin_id", referencedColumnName="id") 
private User admin; 
引起

當您刪除組時,關聯的用戶將通過級聯刪除,然後通過另一個級聯調用刪除所有關聯的組。

它看起來像User實體是父親,因爲它可以有很多組,而該組只能屬於一個用戶。刪除所有用戶組後,刪除所有用戶組是有道理的。所以我建議只在那裏離開CascadeType.REMOVE