2013-03-12 9 views
48

@UniqueConstraint@Column(ユニーク=真)の違いは何ですか?例えば休止注釈で(ユニーク=真)@UniqueConstraintと@Column

@Table(
    name = "product_serial_group_mask", 
    uniqueConstraints = {@UniqueConstraint(columnNames = {"mask", "group"})} 
) 

そして

@Column(unique = true) 
@ManyToOne(optional = false, fetch = FetchType.EAGER) 
private ProductSerialMask mask; 

@Column(unique = true) 
@ManyToOne(optional = false, fetch = FetchType.EAGER) 
private Group group; 
+2

注:Hibernate 5.4では、 'unique = true'を追加したとき、インデックスはスキーム自動アップデータによって追加されませんでした。 '@ UniqueConstraint'が現れました。バグかもしれない。 –

答えて

53

としては@Column(unique = true)は、それが唯一の単一のフィールドであるUniqueConstraintへの近道である、前に言いました。

あなたが与えた例では、両方に大きな違いがあります。

@Column(unique = true) 
@ManyToOne(optional = false, fetch = FetchType.EAGER) 
private ProductSerialMask mask; 

@Column(unique = true) 
@ManyToOne(optional = false, fetch = FetchType.EAGER) 
private Group group; 

このコードはmaskgroup両方がユニークでなければならないことを意味しますが、別に。たとえば、というマスク(mask.id = 1)のレコードがあり、mask.id = 1という別のレコードを挿入しようとすると、その列は一意の値を持つ必要があるため、エラーが発生します。グループについても同じことが言えます。

一方、

@Table(
    name = "product_serial_group_mask", 
    uniqueConstraints = {@UniqueConstraint(columnNames = {"mask", "group"})} 
) 

を合わせマスク+群の値が一意でなければならないことを意味します。それはあなたが、例えば、= 1mask.id = 1group.idでレコードを持っていることを意味し、そしてあなたは、mask.id = 1group.id =を別のレコードを挿入しようとした場合2の場合は、正常に挿入されますが、最初の場合は挿入されません。

あなたはクラスレベルで個別に及びそれに一意であるためにマスクとグループの両方を持っているしたい場合は、次のようなコードを書く必要があるだろう:

@Table(
     name = "product_serial_group_mask", 
     uniqueConstraints = { 
       @UniqueConstraint(columnNames = "mask"), 
       @UniqueConstraint(columnNames = "group") 
     } 
) 

これは、同じ効果を持っています最初のコードブロック。ボアズの@とvegemite4meの答え@に加えて

+0

一意の制約が作成されたら、JPAリポジトリの名前で制約を参照できますか? – jDub9

25

のJava EEのドキュメントから:

public abstract boolean unique 

(オプション)プロパティが一意のキーであるかどうか。これは、テーブルレベルの UniqueConstraintアノテーションのショートカットであり、ユニークキー の制約が単一のフィールドのみの場合に便利です。この制約は、プライマリキーマッピングとテーブルレベルで指定された制約に伴う制約 に加えて適用されます。

@Column(unique = true)はランダムな名前(例えばUK_3u5h7y36qqa13y3mauc5xxayq)を生成しながら、

@UniqueConstraint

は、 名前制約にことができます....ボアズの答えに加えて

+0

このコードを使用すると、 @Column(unique = true) @ManyToOne(オプション= false、fetch = FetchType.EAGER) プライベートProductSerialMaskマスク。 @Column(unique = true) @ManyToOne(オプション= false、fetch = FetchType.EAGER) プライベートグループグループ。 私は2つのインデックスを持っていますが、他の方法で使用すると、2つのカラムを組み合わせた1つのインデックスがありますか? –

12

docを参照してください。

制約が関連付けられているテーブルを知ることが役立つことがあります。例えば:

@Table(
    name = "product_serial_group_mask", 
    uniqueConstraints = { 
     @UniqueConstraint(
      columnNames = {"mask", "group"}, 
      name="uk_product_serial_group_mask" 
    ) 
    } 
) 
2

....

ImplicitNamingStrategyを実装することにより自動的に制約の命名規則を作成することができます。あなたはHibernateの初期化中にmetadataBuilderにあなたの命名戦略を追加注意:

metadataBuilder.applyImplicitNamingStrategy(new MyImplicitNamingStrategy()); 

それは@UniqueConstraintのために働く、常にではないが、ランダムな名前(例えばUK_3u5h7y36qqa13y3mauc5xxayq)を生成@Column(unique = true)、ため。

この問題を解決するためのバグレポートがありますので、できる場合はに投票してください。ここに: https://hibernate.atlassian.net/browse/HHH-11586

ありがとう。

関連する問題