wake-up-neo.com

@UniqueConstraint und @Column (unique = true) im Ruhezustand

Was ist der Unterschied zwischen @ UniqueConstraint und @ Column (unique = true)?

Beispielsweise:

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

Und

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

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

Wie bereits erwähnt, ist @Column(unique = true) eine Verknüpfung zu UniqueConstraint, wenn es sich nur um ein einzelnes Feld handelt.

Aus dem Beispiel, das Sie gegeben haben, ergibt sich ein großer Unterschied zwischen beiden.

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

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

Dieser Code impliziert, dass sowohl mask als auch group eindeutig sein müssen, jedoch getrennt. Das heißt, wenn Sie zum Beispiel einen Datensatz mit mask.id = 1 haben und versuchen, einen weiteren Datensatz mit mask.id = 1 einzufügen, Sie erhalten eine Fehlermeldung, da diese Spalte eindeutige Werte haben sollte. Gleiches gilt für die Gruppe.

Auf der anderen Seite,

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

Impliziert, dass die kombinierten Werte von Maske + Gruppe eindeutig sein sollten. Das heißt, Sie können beispielsweise einen Datensatz mit mask.id = 1 und group.id = 1 haben und versuchen, einen anderen Datensatz einzufügen mit mask.id = 1 und group.id = 2 wird es erfolgreich eingefügt, im ersten Fall jedoch nicht.

Wenn Sie möchten, dass Maske und Gruppe separat und auf Klassenebene eindeutig sind, müssen Sie den Code wie folgt schreiben:

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

Dies hat den gleichen Effekt wie der erste Codeblock.

124

Aus der Java EE Dokumentation:

public abstract boolean unique

(Optional) Gibt an, ob die Eigenschaft ein eindeutiger Schlüssel ist. Dies ist eine Verknüpfung für die Annotation UniqueConstraint auf Tabellenebene und hilfreich, wenn die Einschränkung für eindeutige Schlüssel nur ein einzelnes Feld ist. Diese Einschränkung gilt zusätzlich zu allen Einschränkungen, die durch die Primärschlüsselzuordnung verursacht werden, und für Einschränkungen, die auf Tabellenebene angegeben werden.

Siehe doc

27
Boaz

Zusätzlich zu Boaz Antwort ....

Mit @UniqueConstraint Können Sie die Einschränkung benennen, während @Column(unique = true) einen zufälligen Namen generiert (z. B. UK_3u5h7y36qqa13y3mauc5xxayq).

Manchmal kann es hilfreich sein zu wissen, mit welcher Tabelle eine Einschränkung verknüpft ist. Z.B.:

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

Zusätzlich zu den Antworten von @ Boaz und @ vegemite4me ....

Durch die Implementierung von ImplicitNamingStrategy können Sie Regeln für die automatische Benennung der Einschränkungen erstellen. Beachten Sie, dass Sie Ihre Namensstrategie während der Hibernate-Initialisierung zu metadataBuilder hinzufügen:

metadataBuilder.applyImplicitNamingStrategy(new MyImplicitNamingStrategy());

Dies funktioniert für @UniqueConstraint, Jedoch nicht für @Column(unique = true), das immer einen zufälligen Namen generiert (z. B. UK_3u5h7y36qqa13y3mauc5xxayq).

Es gibt einen Fehlerbericht, der dieses Problem behebt. Wenn Sie können, stimmen Sie dort ab, damit dies implementiert wird. Hier: https://hibernate.atlassian.net/browse/HHH-11586

Vielen Dank.

5
MarcG