web-dev-qa-db-fra.com

@UniqueConstraint et @Column (unique = true) dans une annotation en veille prolongée

Quelle est la différence entre @ UniqueConstraint et @ Column (unique = true)?

Par exemple:

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

Et

@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

Comme indiqué précédemment, @Column(unique = true) est un raccourci vers UniqueConstraint lorsqu'il ne s'agit que d'un seul champ.

D'après l'exemple que vous avez donné, il y a une énorme différence entre les deux.

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

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

Ce code implique que mask et group doivent être uniques, mais séparément. Cela signifie que si, par exemple, vous avez un enregistrement avec un mask.id = 1 et essayez d'insérer un autre enregistrement avec mask.id = 1, vous obtiendrez une erreur, car cette colonne doit avoir des valeurs uniques. Les mêmes aplies pour le groupe.

D'autre part,

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

Cela implique que les valeurs de masque + groupe combinées doivent être uniques. Cela signifie que vous pouvez avoir, par exemple, un enregistrement avec mask.id = 1 et group.id = 1, et si vous essayez d'insérer un autre enregistrement avec mask.id = 1 et group.id = 2, il sera inséré avec succès, alors que dans le premier cas, ce ne serait pas le cas.

Si vous souhaitez que le masque et le groupe soient uniques séparément et au niveau de la classe, vous devez écrire le code comme suit:

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

Cela a le même effet que le premier bloc de code.

124
Glauber Néspoli

De la Java EE:

public abstract boolean unique

(Facultatif) Indique si la propriété est une clé unique. Il s'agit d'un raccourci pour l'annotation UniqueConstraint au niveau de la table. Il est utile lorsque la contrainte de clé unique est constituée d'un seul champ. Cette contrainte s'applique en plus de toute contrainte liée au mappage de clé primaire et aux contraintes spécifiées au niveau de la table.

Voir doc

27
Boaz

En plus de la réponse de Boaz ....

@UniqueConstraint Vous permet de nommer la contrainte, alors que @Column(unique = true) génère un nom aléatoire (par exemple, UK_3u5h7y36qqa13y3mauc5xxayq).

Parfois, il peut être utile de savoir à quelle table est associée une contrainte. Par exemple.:

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

En plus des réponses de @ Boaz et @ vegemite4me ....

En implémentant ImplicitNamingStrategy, vous pouvez créer des règles pour nommer automatiquement les contraintes. Notez que vous ajoutez votre stratégie de nommage au metadataBuilder lors de l'initialisation d'Hibernate:

metadataBuilder.applyImplicitNamingStrategy(new MyImplicitNamingStrategy());

Cela fonctionne pour @UniqueConstraint, Mais pas pour @Column(unique = true), qui génère toujours un nom aléatoire (par exemple, UK_3u5h7y36qqa13y3mauc5xxayq).

Il y a un rapport de bogue pour résoudre ce problème, donc si vous le pouvez, votez-y pour que cela soit mis en œuvre. Ici: https://hibernate.atlassian.net/browse/HHH-11586

Merci.

5
MarcG