2012-12-14 62 views
0

所以我有兩個類:FileFileSet,它們有一個由連接表FILE_FILE_SET連接的雙向多關係。Hibernate手動刪除特定的Many-Many關聯

一個文件可以是許多FileSet的一部分,反之亦然。文件集的更改通過@ManytoMany(cascade = CascadeType.All)註釋級聯到單個文件(但不是相反的方式)。尤其是,在FileSet中遇到> 1000個文件並不罕見。我們已經爲這些類啓動並運行了代碼,但是當我們嘗試從FileSets中刪除單個文件時遇到問題:在刪除正確發生時,隨着集中文件數量的增加,刪除所需的時間與O (N^2)。這是因爲當前用於刪除FileSet-File關聯的代碼獲取FileSet的一個實例,刪除該文件,然後使用SaveOrUpdate()保存更新的FileSet,從而保存所有關聯的文件。

這對於小集合來說很好,但在FileSet中有很多文件時會受到限制。不幸的是,FileSet對象被保存在代碼中的其他許多點上,因爲級聯是一件好事,所以我寧願不要完全關閉級聯。

因此,爲了達到我的實際問題:有沒有辦法在休眠中刪除兩個對象之間的特定關聯?例如,是否有可以運行從連接表中刪除條目的HQL查詢?

回答

2

首先,在ManyToXxx關聯上的CascadeType.ALL沒有多大意義。如果文件集的文件是另一個文件集的一部分,則在刪除文件集時不希望刪除所有文件,因爲它們仍由其他文件集引用。

現在,回答這個問題,你希望它從文件集中刪除文件。這簡直是​​從文件集合中的文件集刪除文件來完成:

public removeFilesFromFileSet(FileSet fileSet, Set<File> filesToRemove) { 
    fileSet.getFiles().removeAll(filesToRemove); 
} 

這將加載文件集中的所有文件,但。如果你不想這樣做,那麼你必須映射關聯表,或者使用SQL。

+0

嗯,這不是我的代碼最初:我不知道爲什麼它不是多對一,但。當前的代碼會按照您描述的方式刪除文件:問題是這也會將所有其他文件重新保存在FileSet中。 – RoryB

+0

它不應該。你說你在你的問題中調用saveOrUpdate()。請注意,我的答案沒有。所以它不應該級聯任何東西。我想你的意思是OneToMany。 –

+0

嗯,你可能是對的:我現在就放棄它。 – RoryB