120 votes

@UniqueConstraint et @Column(unique = true) dans une annotation hibernate

Quelle est la différence entre @UniqueConstraint y @Colonne(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;

183voto

Glauber Néspoli Points 2182

Comme dit précédemment, @Column(unique = true) est un raccourci pour 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 les deux mask y group doivent être uniques, mais distincts. Cela signifie que si, par exemple, vous avez un enregistrement avec un mask.id = 1 et essaie d'insérer un autre enregistrement avec mask.id = 1 vous obtiendrez une erreur, car cette colonne doit avoir des valeurs uniques. La même chose s'applique au groupe.

D'un autre côté,

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

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 y groupe.id = 1 et si vous essayez d'insérer un autre enregistrement avec l'option mask.id = 1 y groupe.id = 2 il sera inséré avec succès, alors qu'il ne le sera pas dans le premier cas.

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

@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.

27voto

Boaan Points 1809

Dans la documentation de 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 et s'avère utile lorsque la contrainte de clé unique ne concerne qu'un seul champ. Cette contrainte s'applique en plus de toute contrainte impliquée par le mappage de la clé primaire et aux contraintes spécifiées au niveau de la table.

Voir doc

25voto

vegemite4me Points 1009

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

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

Il peut parfois être utile de savoir à quelle table une contrainte est associée. Par exemple :

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

6voto

marcg Points 110

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

En mettant en œuvre ImplicitNamingStrategy vous pouvez créer des règles pour nommer automatiquement les contraintes. Notez que vous ajoutez votre stratégie de nommage à l'élément metadataBuilder pendant l'initialisation d'Hibernate :

metadataBuilder.applyImplicitNamingStrategy(new MyImplicitNamingStrategy());

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

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

Merci.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X