JPAアノテーションを使用して複数列制約を導入するにはどうすればよいですか?


90

JPAにマップされたエンティティにマルチキー制約を導入しようとしています:

public class InventoryItem {
    @Id
    private Long id;

    @Version 
    private Long version;

    @ManyToOne
    @JoinColumn("productId")
    private Product product;

    @Column(nullable=false);
    private long serial;
}

基本的に(製品、シリアル)ペアは一意である必要がありますが、シリアルは一意であると言う方法を見つけました。異なる製品が同じシリアル番号を持っている可能性があるため、これは明らかに良い考えではありません。

JPAを介してこの制約を生成する方法はありますか、それとも手動でDBに作成する必要がありますか?

回答:


185

@Table(uniqueConstraints = ...)エンティティクラスのアノテーションを使用して、一意の制約を宣言できます。

@Entity
@Table(uniqueConstraints={
    @UniqueConstraint(columnNames = {"productId", "serial"})
}) 
public class InventoryItem {
    ...
}

これはデータベースに一意の制約を魔法のように作成するわけではないことに注意してください。それを作成するにはDDLが必要です。しかし、JPAエンティティ定義に基づいてデータベースを作成するために、ある種の自動化ツールを使用しているようです。


1
制約がすでに設定されている既存のデータベースには、このようなものが必要ですか?
Rob

制約が作成されると思います。JPAプロバイダーはデータベースを作成しています。
AlanObject

一意性は(productId)列と(serial)列、または合計2列の制約(productId、serial)ですか?
P Satish Patro

68

すでに回答したように、@Table注釈を使用して複数列のインデックスを追加できます。ただし、columnNamesクラス属性ではなく、実際のDB列の名前である必要があります。したがって、列が次のような場合:

@Column(name="product_id")
Long productId;

その場合、@Table注釈は次のようになります。

@Table(uniqueConstraints=
       @UniqueConstraint(columnNames = {"product_id", "serial"}) 

9
これは非常に重要な説明です:オブジェクト名ではなくテーブル名。
カラバシン2017年

1
一意性は(productId)列と(serial)列、または合計2列の制約(productId、serial)ですか?
P Satish Patro

Kotlin:この回答を見て、kotlinの例を見つけてください:stackoverflow.com/a/47000044/285431
Dirk

構文エラー。@Tableアノテーションの閉じ括弧がありません。
Evvo
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.