2013-01-14 5 views
8

ムービーを管理するために、Hibernate/Springアプリケーションで作業しています。データベースにオブジェクトが存在しない場合は保存します(Hibernate&Spring)

クラスムービーは、クラスジャンルと多少の関係を持っています。 これらのクラスはどちらも、GeneratedValueアノテーションを使用してIDを生成しています。

ジャンルは、@カスケード(CascadeType.SAVE_UPDATE)を使用してムービーオブジェクトを介して保存されます ジャンルのタイプ属性(これは「ファンタジー」など)に一意制約を設定しました。

私が今したいのは、すでに "ファンタジー"タイプのジャンルがあるかどうかを確認して、新しいレコードを挿入しようとするのではなく、そのジャンルのIDを使用することです。 (後者は明らかにエラーが発生します)

最後に、select-before-updateのようなものですが、select-before-saveと似ています。

このような関数はHibernateにはありますか?

いくつかのコード:

Movieクラス

@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

私は、休止状態にはいくつかの機能があることを期待していましたが、それも良い解決策です。 @ jordan002が言ったように、私はこの問題を考え過ぎていました。 – Mike

+0

Insert-if-existsは非常に一般的な操作です...私はHibernateがこれを提供していないことを悲しく思っています。 –

答えて

5

あなたはこれを過度に考えているかもしれません。セレクト・ア・アップデート前/セーブ・ビフォー・セーブ・オプションは、2回のDBラウンドトリップ、セレクト用の最初のセッティング、および必要であれば挿入用のセカンド・セービングになります。

あなたが最初からジャンルの多くを持っていないことを知っている場合は、1 RTでこれを行うためのオプションのカップルを持っていますほとんどの時間:

  1. Hibernateの二次キャッシュGenresのすべてではないにしても多くを保持することができ、存在をチェックするときに単純なハッシュテーブルルックアップ(単一のノードを前提とする)が行われます。
  2. ジャンルはすべて既に存在しているものとみなし、session.load()を使用し、存在しないジャンルを参照するときにスローされる行が見つからない例外の結果として新しい挿入を処理します。

現実的には、たくさんのトランザクションについて話していない限り、保存/更新前の簡単な事前クエリではパフォーマンスが低下することはありません。

3

選択し、更新前/選択ビフォアsave これらの状況では、HibernateをJDBCのように扱うべきです。

最初に、あなたがそのようなジャンルを持っているかどうかを知りたい場合は、それを問い合わせる必要があります。

とするとそれをムービーに追加すると、SAVE_UPDATEは新しいものを作成しません。 そうしないと、Hibernateはデータベースに新しいGenre行を作成し、many_to_manyテーブルへの接続を追加します。

+0

+1ありがとうございますが、これはさらにいくつかのルックアップにつながる可能性があります。新しいジャンルごとに、私はdbを再クエリーする必要があります。 – Mike

+1

Selectは、特にこのような小さなテーブル(非常に多くのジャンルを持っていると期待しています)で非常に高速なパフォーマンスを発揮します。同様に、サーバー上にそのテーブルのライブレコードを保持している場合も同様です。あなたはそれを一度キャッシュし、サーバがアライブされている限り、それを後で維持するだけで済むかもしれません – Gleeb

関連する問題