2013-01-14 35 views
8

我正在處理一些Hibernate/Spring應用程序來管理一些電影。保存數據庫中的對象,如果它不存在(Hibernate&Spring)

班級電影與班級流派之間存在多對多的關係。 這兩個類都使用GeneratedValue註釋生成了id。

通過使用@Cascade(CascadeType.SAVE_UPDATE) 通過電影對象保存流派我已經對流派的類型屬性(例如名稱;「幻想」)設置了唯一約束。

我現在想要做的是讓Hibernate檢查是否已經有類型爲「Fantasy」的流派,如果有,使用該流派的ID而不是嘗試插入新記錄。 (後者顯然會引發錯誤)

最後,我需要的是像select-before-update之類的東西,但更像是select-before-save。

Hibernate中有這樣的函數嗎?

一些代碼:

電影類

@Entity 
public class Movie { 

@Id 
@GeneratedValue(strategy=GenerationType.AUTO) 
private int id; 

private String name; 

@Lob 
private String description; 

@Temporal(TemporalType.TIME) 
private Date releaseDate; 

@ManyToMany 
@Cascade(CascadeType.SAVE_UPDATE) 
private Set<Genre> genres = new HashSet<Genre>(); 

.... //other methods 

體裁類

@Entity 
public class Genre { 

@Column(unique=true) 
private String type; 

@Id 
@GeneratedValue(strategy=GenerationType.AUTO) 
private int id 

....//other methods 
+0

你可以在電影的單獨查詢體裁實體,看看是否已經有一個「幻想」流派?你也可以初始化流派設置並迭代它,看看你的流派是否存在 – Gleeb

+0

我曾經希望hibernate有這個功能,但是,這是一個很好的解決方案。正如@ jordan002所說,我正在解決問題。 – Mike

+0

Insert-if-exists是一種非常常見的操作......我發現Hibernate並沒有提供這個功能,我們不得不用檢查來混淆我們的代碼。 –

回答

5

你可能在想這個。任何select-before-update/save-before-save選項將導致2個數據庫往返行程,第一個用於選擇,第二個用於插入(如有必要)。

如果你知道你會不會有很多從一開始就流派,你有兩個選擇在1 RT大部分時間做這個:

  1. Hibernate的二級緩存可以容納很多(如果不是全部)流派,那麼當您檢查存在時會導致簡單的散列表查找(假設是單個節點)。
  2. 你可以假設你的所有流派都已經存在了,使用session.load(),並且處理新的插入是由於當你引用一個尚不存在的流派時引發的行未找到的異常。

但是,實際上,除非你在談論很多交易,否則在保存/更新之前進行簡單的預查詢並不會消滅你的表現。

3

我沒有在Hibernate中聽到這樣的功能的選擇,更新前/選擇,在─保存 在這些情況下,您應該像對待JDBC那樣對待Hibernate。

首先,如果你想知道你是否有這樣的流派,你應該查詢它。

如果你這樣做。那麼當您將其添加到電影時,SAVE_UPDATE將不會創建新的。如果你不這樣做,Hibernate將在數據庫中創建一個新的Genre行,並將連接添加到many_to_many表中。

+0

+1謝謝,但這可能也會導致更多外觀。對於我添加的每一個新流派,我都必須重新查詢數據庫。 – Mike

+1

選擇具有非常快的性能,特別是在這樣的小桌子上(您真正期望擁有多少流派)。以及如果您在服務器上保留該表的實時記錄。你可能只需要緩存一次,並且只要服務器很合適,以後再維護它 – Gleeb

相關問題