2009-08-24 6 views
27

lo que quiero:¿Puedo hacer que una entidad Hibernate incrustada no se pueda nulos?

@Embedded(nullable = false) 
private Direito direito; 

Sin embargo, como saben que no hay tal atributo a @Embeddable.

¿Hay una forma correcta de hacerlo? No quiero soluciones.

+0

¿Quieres decir un elemento compuesto? – Zoidberg

+0

Sí. ¿Por qué no puedo responder con menos de 15 caracteres? –

+0

No estoy seguro de cómo hacerlo con las anotaciones, pero puedo mostrarle el xml – Zoidberg

Respuesta

33

Los componentes incrustados (o elementos compuestos, como quiera llamarlos) generalmente contienen más de una propiedad y, por lo tanto, se asignan a más de una columna. Todo el componente que es nulo, por lo tanto, se puede tratar de diferentes maneras; La especificación J2EE no dicta una forma u otra.

Hibernate considera que el componente es NULL si todas sus propiedades son NULL (y viceversa). Por lo tanto, puede declarar que una (cualquiera) de las propiedades no es nula (dentro de @Embeddable o como parte de en @Embedded) para lograr lo que desea.

Alternativamente, si está utilizando el Validador de Hibernate puede anotar su propiedad con @NotNull, aunque esto solo dará como resultado la verificación del nivel de la aplicación, no el nivel de DB.

+0

+1, una buena respuesta – skaffman

+0

¡Gracias! Agregará @Nullable a una propiedad del compuesto. –

+0

No funciona para mí. ¿Es posible que exista un problema si '@ Embeddable' tiene solo un campo, que está anotado con' @Access (AccessType.FIELD) '? –

11

Agregue el campo ficticio a la clase que está marcado @Embeddable.

@Formula("0") 
private int dummy; 

Ver https://issues.jboss.org/browse/HIBERNATE-50.

+0

¿Aún funciona para usted? Para mí no ... –

+0

Está trabajando con Hibernate 3.5.3-Final. – adam0404

+0

No funciona para mí con Hibernate 4.3.7.Final (intenté varias cosas similares, ninguna funcionó) – NoUsername

1

No estaba demasiado emocionado con ninguna de las sugerencias hechas anteriormente, así que creé un aspecto que manejaría esto para mí.

Esto no se ha probado completamente, y definitivamente no se ha probado en las colecciones de objetos incrustados, por lo que debe tener cuidado con el comprador. Sin embargo, parece funcionar para mí hasta ahora.

Básicamente, intercepta el captador al campo @Embedded y se asegura de que el campo esté ocupado.

public aspect NonNullEmbedded { 

    // define a pointcut for any getter method of a field with @Embedded of type Validity with any name in com.ia.domain package 
    pointcut embeddedGetter() : get(@javax.persistence.Embedded * com.company.model..*); 


    /** 
    * Advice to run before any Embedded getter. 
    * Checks if the field is null. If it is, then it automatically instantiates the Embedded object. 
    */ 
    Object around() : embeddedGetter(){ 
     Object value = proceed(); 

     // check if null. If so, then instantiate the object and assign it to the model. 
     // Otherwise just return the value retrieved. 
     if(value == null){ 
      String fieldName = thisJoinPoint.getSignature().getName(); 
      Object obj = thisJoinPoint.getThis(); 

      // check to see if the obj has the field already defined or is null 
      try{ 
       Field field = obj.getClass().getDeclaredField(fieldName); 
       Class clazz = field.getType(); 
       value = clazz.newInstance(); 
       field.setAccessible(true); 
       field.set(obj, value); 
      } 
      catch(NoSuchFieldException | IllegalAccessException | InstantiationException e){ 
       e.printStackTrace(); 
      } 
     } 

     return value; 
    } 
} 
1

Puede usar un captador nullsafe.

public Direito getDireito() { 
    if (direito == null) { 
     direito = new Direito(); 
    } 
    return direito; 
} 
+5

Tenga en cuenta que esto hará que su entidad se marque como sucia en cada lectura, lo que provocará que Hibernate aumente la versión. Esto conducirá a excepciones de bloqueo optimistas. – Arlo

+0

Esta solución activa las instrucciones de actualización sql en el servidor de base de datos, lo que trae problemas como concurrencia entre subprocesos y problemas de rendimiento. –

Cuestiones relacionadas