Pregunta

Lo que quiero:

@Embedded(nullable = false)
private Direito direito;

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

¿Hay una manera correcta de hacer esto? No quiero soluciones.

¿Fue útil?

Solución

Los componentes insertable (o elementos compuestos, lo que quieras llamarlos) suelen contener más de una propiedad y por lo tanto se asignan a más de una columna. Por consiguiente, el ser componente de toda nulo puede ser tratada de diferentes maneras; especificación J2EE no dicta una forma u otra.

Hibernate considera componente a NULL si todas sus propiedades son NULL (y viceversa). Por lo tanto, puede declarar una (cualquiera) de las propiedades de ser no nulo (ya sea dentro @Embeddable o como parte de @AttributeOverride en @Embedded) para conseguir lo que quiere.

Por otra parte, si usted está usando Hibernate Validator puede anotar su propiedad con @NotNull aunque esto sólo resultará en jaque a nivel de aplicación, no db-nivel.

Otros consejos

Es posible usar "hibernate.create_empty_composites.enabled", ya que Hibernate 5.1 para cambiar este comportamiento (ver https://hibernate.atlassian.net/browse/HHH-7610 )

Añadir campo ficticio en la clase que está marcado @Embeddable.

@Formula("0")
private int dummy;

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

Yo no estaba muy emocionado con cualquiera de las sugerencias hechas anteriormente, así que creé un aspecto que se ocuparía de esto por mí.

Esto no está completamente probado, y definitivamente no probado contra las colecciones de objetos incrustados, por lo que el comprador y el cuidado. Sin embargo, parece que funciona para mí hasta ahora.

Básicamente, intercepta el getter al campo @Embedded y asegura que el campo se rellena.

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

Puede utilizar un captador nullsafe.

public Direito getDireito() {
    if (direito == null) {
        direito = new Direito();
    }
    return direito;
}
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top