Wie führe ich eine mehrspaltige Einschränkung mit JPA-Anmerkungen ein?

89

Ich versuche, eine Mehrschlüsseleinschränkung für eine JPA-zugeordnete Entität einzuführen:

public class InventoryItem {
    @Id
    private Long id;

    @Version 
    private Long version;

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

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

Grundsätzlich sollte (Produkt-, Serien-) Paar eindeutig sein, aber ich habe nur einen Weg gefunden zu sagen, dass Serien eindeutig sein sollten. Dies ist offensichtlich keine gute Idee, da verschiedene Produkte möglicherweise die gleichen Seriennummern haben.

Gibt es eine Möglichkeit, diese Einschränkung über JPA zu generieren, oder bin ich gezwungen, sie manuell in der Datenbank zu erstellen?

plouh
quelle

Antworten:

182

Sie können eindeutige Einschränkungen mithilfe der @Table(uniqueConstraints = ...)Anmerkung in Ihrer Entitätsklasse deklarieren , d. H.

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

Beachten Sie, dass dadurch die eindeutige Einschränkung in der Datenbank nicht auf magische Weise erstellt wird. Sie benötigen dennoch eine DDL, damit sie erstellt werden kann. Anscheinend verwenden Sie jedoch ein automatisiertes Tool zum Erstellen der Datenbank basierend auf JPA-Entitätsdefinitionen.

psp
quelle
1
Wird so etwas für eine vorhandene Datenbank mit bereits vorhandenen Einschränkungen benötigt?
Rob
Ich glaube, dass die Einschränkung erstellt wird, wenn der JPA-Anbieter die Datenbank erstellt.
AlanObject
Die Eindeutigkeit gilt für die Spalte (productId) und die Spalte (serial) oder für die Einschränkung von insgesamt 2 Spalten (productId, serial).
P Satish Patro
66

Wie bereits beantwortet, kann ein mehrspaltiger Index mithilfe von @TableAnmerkungen hinzugefügt werden . Allerdings columnNamesmuss der Name der tatsächlichen DB Spalten sein, nicht das Klassenattribut. Wenn die Spalte also wie folgt aussieht:

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

Dann sollte die @TableAnmerkung wie folgt aussehen

@Table(uniqueConstraints=
       @UniqueConstraint(columnNames = {"product_id", "serial"}) 
SJha
quelle
8
Dies ist eine sehr wichtige Klarstellung: Tabellennamen und keine Objektnamen.
Calabacin
1
Die Eindeutigkeit gilt für die Spalte (productId) und die Spalte (serial) oder für die Einschränkung von insgesamt 2 Spalten (productId, serial).
P Satish Patro
Kotlin: Schauen Sie sich diese Antwort an, um ein Beispiel für Kotlin zu finden: stackoverflow.com/a/47000044/285431
Dirk
Syntax-Fehler. Sie vermissen die schließende Klammer in der @ Table-Annotation.
Evvo