@Basic (optionnel = false) vs @Column (nullable = false) dans JPA

Réponses:

98

Gordon Yorke (membre du comité d'architecture d'EclipseLink, responsable technique de TopLink Core, membre du groupe d'experts JPA 2.0) a écrit une bonne réponse sur ce sujet, donc au lieu de le paraphraser, je vais citer sa réponse :

La différence entre optionalet nullableest la portée à laquelle ils sont évalués. La définition de « optional» parle des valeurs de propriété et de champ et suggère que cette fonctionnalité doit être évaluée au cours de l'exécution. « nullable» fait uniquement référence aux colonnes de la base de données.

Si une implémentation choisit de l'implémenter, optionalces propriétés doivent être évaluées en mémoire par le fournisseur de persistance et une exception levée avant que SQL ne soit envoyé à la base de données, sinon lors de l'utilisation de violations ' updatable=false' ' optional', les violations ne seront jamais signalées.

Pascal Thivent
la source
8
Alors, lequel devrait vraiment être utilisé, peut-être les deux?
Xiè Jìléi le
39
@Xie Jilei: Extrait du livre: Java persistence with hibernate 2007, p. 179: @Basic(optional = false) @Column(nullable = false)L'annotation @Basic marque la propriété comme non facultative au niveau de l'objet Java. Le deuxième paramètre, nullable = false sur le mappage de colonne, est uniquement responsable de la génération d'une contrainte de base de données NOT NULL. L'implémentation Hibernate JPA traite les deux options de la même manière dans tous les cas, vous pouvez donc aussi n'utiliser qu'une seule des annotations à cette fin.
rapt
2
@rapt - Je ne comprends pas The @Basic annotation marks the property as not optional on the Java object level.Qu'est-ce que cela signifie? Donc, @Basicc'est comme dire que créer la colonne de base de données NOT NULLpour ladite variable?
Erran Morad
9
Cela signifie que si vous essayez de conserver une entité avec un champ nul, une exception sera levée si elle est marquée comme facultative = false (sans contacter la base de données) et que l'entité ne sera pas ajoutée au contexte de persistance JPA. S'il est seulement annoté pour être nullable = false, l'entité sera ajoutée au contexte de persistance et en essayant d'écrire l'entité dans la base de données (par exemple via flush), elle essaiera d'écrire l'entité dans la base de données, ce qui refusera cela et il lèvera alors une exception.
Ray Hulha
@RayHulha J'ai essayé d'annoter un champ avec "@Basic (optional = false)", et j'ai ajouté un tuple à la base de données (avec la valeur de ce champ = null), aucune exception n'a été soulevée !!, j'espère que vous pouvez expliquer pour moi ce comportement.
ziMtyth
4

J'ai donc essayé l'annotation @Basic (facultatif = false) en utilisant JPA 2.1 (EclipseLink) et il s'avère que l'annotation est ignorée dans l'utilisation réelle (au moins pour un champ String). (par exemple, les appels entityManager.persist).

Je suis donc allé à la spécification et j'ai lu à ce sujet. Voici ce que la spécification a à dire:
http://download.oracle.com/otndocs/jcp/persistence-2.0-fr-oth-JSpec/

De base (facultatif): indique si la valeur du champ ou de la propriété peut être nulle. Ceci est un indice et n'est pas pris en compte pour les types primitifs; il peut être utilisé dans la génération de schéma.

Je pense donc que cette phrase explique le cas d'utilisation réel de Basic (facultatif), il est utilisé dans la génération de schéma. (C'est-à-dire: lorsque vous générez CREATE TABLE SQL à partir de classes d'entité Java. C'est quelque chose qu'Hibernate peut faire par exemple.)

Ray Hulha
la source
1
C'est drôle que l'autre réponse implique qu'il est nullable et non Basic qui est utilisé pour la génération de schéma (quand il dit «'nullable' est uniquement en référence aux colonnes de la base de données»). C'est encore très déroutant. Je suppose que nullable est utilisé pour la génération de schéma et que Basic (facultatif = false) peut être utilisé dans le même but? Cela a-t-il du sens?
marcus
optional = falsesert uniquement à vérifier cette contrainte lors de l'exécution. nullable = falsecrée une contrainte de base de données. Pour les applications, définir également a du optional = falsesens, car il est évalué plus rapidement que d'aller à la base de données et de vérifier cette contrainte là-bas ..
nimo23