264 votes

Confusion : @NotNull vs. @Column(nullable = false) avec JPA et Hibernate

  1. Lorsqu'ils apparaissent sur un champ/objet d'une @Entity Quelle est la différence entre les deux ? (Je persiste l'entité à travers Hibernate ).

  2. À quel cadre et/ou spécification chacun d'entre eux appartient-il ?

  3. @NotNull est situé dans javax.validation.constraints . Dans le javax.validation.constraints.NotNull La javadoc dit

    L'élément annoté ne doit pas être nul

    mais il ne parle pas de la représentation de l'élément dans la base de données, alors pourquoi ajouter la contrainte nullable=false à la colonne ?

348voto

Ryan Stewart Points 46960

@NotNull est un JSR 303 Validation des haricots annotation. Elle n'a rien à voir avec les contraintes de base de données proprement dites. Toutefois, Hibernate étant l'implémentation de référence de la norme JSR 303, il détecte intelligemment ces contraintes et les traduit en contraintes de base de données pour vous, de sorte que vous en obtenez deux pour le prix d'un. @Column(nullable = false) est la manière JPA de déclarer qu'une colonne n'est pas nulle. En d'autres termes, la première est destinée à la validation et la seconde à l'indication des détails du schéma de la base de données. Vous obtenez simplement une aide supplémentaire (et bienvenue !) d'Hibernate sur les annotations de validation.

2 votes

Merci ! Donc, si je veux que ma persistance JPA ne soit pas liée à l'implémentation d'Hibernate (c'est-à-dire passer à EJB3), je dois utiliser les deux annotations (pour interdire les nullités dans le champ et sa colonne) ?

3 votes

Je ne sais pas. Il n'existe aucune spécification indiquant qu'un fournisseur JPA doit reconnaître les annotations JSR 303, mais cela ne signifie pas que les autres fournisseurs ne le font pas. Je ne peux pas dire si l'un d'entre eux le fait ou non.

7 votes

Les fournisseurs JPA ne sont pas tenus de fournir une implémentation JSR303, mais doivent, conformément aux spécifications, fournir la possibilité d'intégrer une implémentation JSR303 tierce. Ainsi, bien qu'Hibernate fournisse JSR303, vous pouvez, pour une raison quelconque, décider de ne pas l'utiliser et d'opter pour quelqu'un d'autre ou d'utiliser une implémentation JPA comme openJPA et faire appel à quelqu'un d'autre pour fournir JSR303. Notez également que l'implémentation JPA d'Hibernate est également EJB3. Il est incorrect de dire "si je veux que ma persistance JPA ne soit pas liée à l'implémentation Hibernate (c'est-à-dire passer à EJB3)", JPA fait partie de la spécification EJB3.

20voto

Sebastian Theek Points 181

Les versions les plus récentes du fournisseur JPA d'Hibernate appliquent les contraintes de validation du bean (JSR 303) de la manière suivante @NotNull à la DDL par défaut (grâce à hibernate.validator.apply_to_ddl property La valeur par défaut est true ). Mais il n'y a aucune garantie que les autres fournisseurs JPA le fassent ou aient même la capacité de le faire.

Vous devez utiliser les annotations de validation des haricots comme @NotNull pour s'assurer que les propriétés des beans sont définies sur une valeur non nulle, lors de la validation des beans java dans la JVM (cela n'a rien à voir avec les contraintes de base de données, mais dans la plupart des situations, cela devrait y correspondre).

Vous devez en outre utiliser l'annotation JPA telle que @Column(nullable = false) pour donner au fournisseur jpa des indications pour générer la bonne DDL afin de créer des colonnes de table avec les contraintes de base de données que vous souhaitez. Si vous pouvez ou souhaitez vous appuyer sur un fournisseur JPA comme Hibernate, qui applique par défaut les contraintes de validation du bean à la DDL, vous pouvez les omettre.

19voto

Vlad Mihalcea Points 3628

L'APP @Column Annotation

El nullable de l'attribut @Column a deux objectifs :

  • il est utilisé par l'outil de génération de schéma
  • il est utilisé par Hibernate lors du vidage du Contexte de Persistance

Outil de génération de schémas

L'outil de génération de schémas HBM2DDL traduit les données de la base de données de l'UE. @Column(nullable = false) à un attribut d'entité NOT NULL pour la colonne de la table associée lors de la génération du fichier CREATE TABLE déclaration.

Comme je l'ai expliqué dans le Guide de l'utilisateur d'Hibernate il est préférable d'utiliser un outil tel que Voie de migration au lieu de s'appuyer sur le mécanisme HBM2DDL pour générer le schéma de la base de données.

Vidage du contexte de persistance

Lors du vidage du contexte de persistance, Hibernate ORM utilise également la fonction @Column(nullable = false) attribut de l'entité :

new Nullability( session ).checkNullability( values, persister, true );

Si la validation échoue, Hibernate envoie un message d'erreur PropertyValueException et empêche l'exécution nécessaire de l'instruction INSERT ou UPDATE :

if ( !nullability[i] && value == null ) {
    //check basic level one nullablilty
    throw new PropertyValueException(
            "not-null property references a null or transient value",
            persister.getEntityName(),
            persister.getPropertyNames()[i]
        );    
}

La validation du haricot @NotNull Annotation

El @NotNull est définie par Bean Validation et, tout comme l'ORM Hibernate est l'implémentation JPA la plus populaire, l'implémentation Bean Validation la plus populaire est l'annotation Validateur Hibernate cadre.

Lorsque vous utilisez le validateur Hibernate avec l'ORM Hibernate, le validateur Hibernate lancera un message d'erreur ConstraintViolation lors de la validation de l'entité.

0 votes

Pourquoi affirmez-vous que flyway est meilleur que le schéma de génération ?

1 votes

C'est une bonne observation. J'ai mis à jour la réponse avec un lien de référence.

0 votes

Merci pour la référence et l'excellente réponse !

13voto

Il est intéressant de noter que toutes les sources soulignent que @Column(nullable=false) est utilisé uniquement pour la génération de DDL.

Cependant, même s'il n'y a pas d'annotation @NotNull, et que l'option hibernate.check_nullability est définie sur true, Hibernate effectuera une validation des entités à persister.

Il lèvera une PropertyValueException indiquant que "la propriété not-null fait référence à une valeur nulle ou transitoire", si les attributs nullable=false n'ont pas de valeurs, même si de telles restrictions ne sont pas mises en œuvre dans la couche de base de données.

Plus d'informations sur l'option hibernate.check_nullability sont disponibles ici : http://docs.jboss.org/hibernate/orm/5.0/userguide/html_single/Hibernate_User_Guide.html#configurations-mapping .

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