Verwirrung: @NotNull vs. @Column (nullable = false) mit JPA und Hibernate

242
  1. @EntityWas ist der Unterschied zwischen ihnen, wenn sie auf einem Feld / Getter von erscheinen ? (Ich bleibe bei der Entität durch den Ruhezustand ).

  2. Zu welchem ​​Framework und / oder welcher Spezifikation gehört jeder von ihnen?

  3. @NotNullbefindet sich innerhalb javax.validation.constraints. Im javax.validation.constraints.NotNullJavadoc heißt es

    Das mit Anmerkungen versehene Element darf nicht null sein

    Es wird jedoch nicht von der Darstellung des Elements in der Datenbank gesprochen. Warum sollte ich die Einschränkung nullable=falseder Spalte hinzufügen ?

verzückt
quelle

Antworten:

328

@NotNullist eine Anmerkung zur JSR 303-Bean-Validierung . Es hat nichts mit Datenbankeinschränkungen selbst zu tun. Da Hibernate die Referenzimplementierung von JSR 303 ist, greift es diese Einschränkungen auf intelligente Weise auf und übersetzt sie für Sie in Datenbankeinschränkungen, sodass Sie zwei zum Preis von einem erhalten. @Column(nullable = false)ist die JPA-Methode zum Deklarieren einer Spalte als nicht null. Das erste dient zur Validierung und das zweite zum Anzeigen von Datenbankschemadetails. Sie erhalten von Hibernate nur zusätzliche (und willkommene!) Hilfe zu den Validierungsanmerkungen.

Ryan Stewart
quelle
2
Vielen Dank! Wenn ich also möchte, dass meine JPA-Persistenz nicht an die Hibernate-Implementierung gebunden ist (dh auf EJB3 wechselt), muss ich beide Annotationen verwenden (um Null sowohl im Feld als auch in der Spalte zu verbieten).
Rapt
3
Ich weiß es nicht. Es gibt keine Spezifikation, die besagt, dass ein JPA-Anbieter JSR 303-Anmerkungen erkennen muss, aber das bedeutet nicht, dass andere Anbieter dies nicht tun. Ich kann nicht sagen, ob jemand etwas tut oder nicht.
Ryan Stewart
7
JPA-Anbieter müssen keine JSR303-Implementierung bereitstellen, müssen jedoch gemäß der Spezifikation die Möglichkeit bieten, sich in eine JSR303-Implementierung eines Drittanbieters zu integrieren. Während Hibernate JSR303 bereitstellt, können Sie sich aus irgendeinem Grund dafür entscheiden, ihre nicht zu verwenden und mit jemand anderem zu arbeiten oder eine JPA-Implementierung wie openJPA zu verwenden und eine andere Person zur Bereitstellung von JSR303 zu verwenden. Beachten Sie auch, dass die JPA-Implementierung von Hibernate ebenfalls EJB3 ist. Es ist falsch zu sagen "Wenn ich möchte, dass meine JPA-Persistenz nicht an die Hibernate-Implementierung gebunden ist (dh Änderung an EJB3)" JPA ist Teil der EJB3-Spezifikation.
Shahzeb
5
@ Shahzeb: Bei der Frage geht es nicht darum, wer die JSR 303-Validierung unterstützt / bereitstellt. Es geht darum , den ORM (n) erkennt JSR 303 Anmerkungen wie @NotNull, @Size, @Min, @Maxetc. und dies in Datenbankbeschränkungen übersetzen.
Ryan Stewart
1
Ja, aber mein Kommentar ist gültig im Zusammenhang mit dem, was OP in dem nachfolgenden Kommentar gefragt hat, den Sie nicht kannten.
Shahzeb
18

Die neuesten Versionen des JPA-Anbieters im Ruhezustand wenden die Bean-Validierungsbeschränkungen (JSR 303) @NotNullstandardmäßig wie DDL an (dank der Standardeinstellungen hibernate.validator.apply_to_ddl propertyvon)true ). Es gibt jedoch keine Garantie dafür, dass andere JPA-Anbieter dies tun oder sogar können.

Sie sollten Anmerkungen @NotNullzur Bean-Validierung verwenden, um sicherzustellen, dass die Bean-Eigenschaften bei der Validierung von Java-Beans in der JVM auf einen Wert ungleich Null gesetzt werden (dies hat nichts mit Datenbankeinschränkungen zu tun, sollte jedoch in den meisten Situationen diesen entsprechen).

Sie sollten zusätzlich die JPA-Annotation verwenden @Column(nullable = false), um dem JPA-Anbieter Hinweise zum Generieren der richtigen DDL zum Erstellen von Tabellenspalten mit den gewünschten Datenbankeinschränkungen zu geben. Wenn Sie sich auf einen JPA-Anbieter wie Hibernate verlassen können oder möchten, der die Bean-Validierungsbeschränkungen standardmäßig auf DDL anwendet, können Sie sie weglassen.

Sebastian Theek
quelle
10

Interessanterweise betonen alle Quellen, dass @Column (nullable = false) nur für die DDL-Generierung verwendet wird.

Selbst wenn keine @ NotNull-Annotation vorhanden ist und die Option hibernate.check_nullability auf true gesetzt ist, führt Hibernate eine Validierung der Entitäten durch, die beibehalten werden sollen.

Es wird eine PropertyValueException ausgelöst, die besagt, dass "Nicht-Null-Eigenschaft auf einen Null- oder Übergangswert verweist", wenn nullable = false-Attribute keine Werte haben, selbst wenn solche Einschränkungen nicht in der Datenbankebene implementiert sind.

Weitere Informationen zur Option hibernate.check_nullability finden Sie hier: http://docs.jboss.org/hibernate/orm/5.0/userguide/html_single/Hibernate_User_Guide.html#configurations-mapping .

Aleksandar Radulović
quelle
7

Die JPA @Column Anmerkung

Das nullableAttribut der@Column Anmerkung hat zwei Zwecke:

  • Es wird vom Schemaerstellungstool verwendet
  • Es wird vom Ruhezustand beim Löschen des Persistenzkontexts verwendet

Schema-Generierungs-Tool

Das HBM2DDL-Schemagenerierungstool übersetzt das @Column(nullable = false)Entitätsattribut NOT NULLbeim Generieren der CREATE TABLEAnweisung in eine Einschränkung für die zugehörige Tabellenspalte .

Wie ich im Hibernate-Benutzerhandbuch erklärt habe , ist es besser, ein Tool wie Flyway zu verwenden, als sich beim Generieren des Datenbankschemas auf den HBM2DDL-Mechanismus zu verlassen.

Persistenz-Kontext-Flush

Beim Löschen des Persistenzkontexts verwendet Hibernate ORM auch das @Column(nullable = false)Entitätsattribut:

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

Wenn die Validierung fehlschlägt, PropertyValueExceptionlöst Hibernate ein aus und verhindert, dass die INSERT- oder UPDATE-Anweisung erforderlich ausgeführt wird:

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]
        );    
}

Weitere Informationen zur Funktionsweise des Hibernate-Spülmechanismus finden Sie in diesem Artikel .

Die Bean Validation @NotNullAnnotation

Die @NotNullAnnotation wird durch Bean Validation definiert. Genau wie Hibernate ORM die beliebteste JPA-Implementierung ist, ist der Hibernate Validator die beliebteste Bean Validation-Implementierung Framework .

Wenn Sie Hibernate Validator zusammen mit Hibernate ORM verwenden, löst Hibernate Validator ConstraintViolationbei der Validierung der Entität ein aus.

Vlad Mihalcea
quelle
Warum ist Flyway Ihrer Meinung nach besser als das Generieren eines Schemas?
Andronicus
1
Das ist eine gute Beobachtung. Ich habe die Antwort mit einem Referenzlink aktualisiert.
Vlad Mihalcea
Vielen Dank für die Referenz und tolle Antwort!
Andronicus