@Basic (opcional = falso) vs @Column (nullable = falso) en JPA

Respuestas:

98

Gordon Yorke (miembro del comité de arquitectura de EclipseLink, líder técnico de TopLink Core, miembro del grupo de expertos de JPA 2.0) escribió una buena respuesta sobre este tema, así que en lugar de parafrasearlo, citaré su respuesta :

La diferencia entre optionaly nullablees el alcance en el que se evalúan. La definición de " optional" habla de valores de propiedad y campo y sugiere que esta característica debe evaluarse dentro del tiempo de ejecución. 'nullable ' solo se refiere a las columnas de la base de datos.

Si una implementación opta por implementar optional, el proveedor de persistencia debe evaluar esas propiedades en la memoria y generar una excepción antes de que SQL se envíe a la base de datos; de lo contrario, cuando se utilicen violaciones ' updatable=false' ' optional', nunca se notificarán.

Pascal Thivent
fuente
8
Entonces, ¿cuál realmente debería usarse, tal vez ambos?
Xiè Jìléi
39
@Xie Jilei: Del libro: Persistencia de Java con hibernate 2007, p. 179: @Basic(optional = false) @Column(nullable = false)La anotación @Basic marca la propiedad como no opcional en el nivel del objeto Java. La segunda configuración, anulable = false en el mapeo de la columna, solo es responsable de la generación de una restricción de base de datos NOT NULL. La implementación de Hibernate JPA trata ambas opciones de la misma manera en cualquier caso, por lo que también puede usar solo una de las anotaciones para este propósito.
rapto
2
@rapt - No entiendo The @Basic annotation marks the property as not optional on the Java object level.¿Qué significa eso? Entonces, ¿solo @Basices como decir que hace la columna NOT NULLde la base de datos para dicha variable?
Erran Morad
9
Es decir, si intenta persistir una entidad con un campo nulo, lanzará una excepción si está marcada como opcional = falso (sin contactar la base de datos) y la entidad no se agregará al contexto de persistencia JPA. Si solo está anotado para ser anulable = falso, la entidad se agregará al contexto de persistencia y cuando intente escribir la entidad en la base de datos (por ejemplo, a través de flush), intentará escribir la entidad en la base de datos que lo negará y lanzará una excepción entonces.
Ray Hulha
@RayHulha Traté de anotar un campo con "@Basic (opcional = falso)", y agregué una tupla a la base de datos (con el valor de este campo = nulo), no se generó ninguna excepción !!, espero que puedas explicar para mí este comportamiento.
ziMtyth
4

Así que probé la anotación @Basic (opcional = falso) usando JPA 2.1 (EclipseLink) y resulta que la anotación se ignora en el uso real (al menos para un campo String). (por ejemplo, llamadas entityManager.persist).

Así que fui a la especificación y leí al respecto. Esto es lo que dice la especificación:
http://download.oracle.com/otndocs/jcp/persistence-2.0-fr-oth-JSpec/

Básico (opcional): si el valor del campo o la propiedad puede ser nulo. Esta es una sugerencia y no se tiene en cuenta para los tipos primitivos; se puede utilizar en la generación de esquemas.

Entonces, creo que esta oración explica el caso de uso real de Basic (opcional) que se usa en la generación de esquemas. (Es decir: cuando genera CREATE TABLE SQL a partir de clases de entidad Java. Esto es algo que Hibernate puede hacer, por ejemplo).

Ray Hulha
fuente
1
Es gracioso que la otra respuesta implique que es anulable y no básico que se usa para la generación de esquemas (cuando dice «'anulable' es solo en referencia a columnas de base de datos»). Sigue siendo muy confuso. ¿Supongo que anulable se usa para la generación de esquemas y Basic (opcional = falso) se puede usar para el mismo propósito? ¿Tiene sentido?
Marcus
optional = falsees solo para verificar esta restricción en tiempo de ejecución. nullable = falsecrea restricción de base de datos. Para las aplicaciones, establecer también optional = falsetiene sentido, porque se evalúa más rápido que ir a la base de datos y verificar esa restricción allí ..
nimo23