Могу ли я сделать встроенный объект Hibernate необнуляемым?

StackOverflow https://stackoverflow.com/questions/1324266

  •  19-09-2019
  •  | 
  •  

Вопрос

Что я хочу:

@Embedded(nullable = false)
private Direito direito;

Однако, как вы знаете, у @Embeddable такого атрибута нет.

Есть ли правильный способ сделать это?Мне не нужны обходные пути.

Это было полезно?

Решение

Встраиваемые компоненты (или составные элементы, как бы вы их ни называли) обычно содержат более одного свойства и, следовательно, сопоставляются более чем с одним столбцом.Поэтому весь компонент, имеющий значение null, можно рассматривать по-разному;Спецификация J2EE не диктует того или иного варианта.

Hibernate считает, что компонент имеет значение NULL, если все его свойства имеют значение NULL (и наоборот).Таким образом, вы можете объявить одно (любое) свойство не нулевым (либо внутри @Embeddable или как часть @AttributeOverride на @Embedded), чтобы достичь желаемого.

Альтернативно, если вы используете Hibernate Validator, вы можете аннотировать свое свойство с помощью @NotNull хотя это приведет только к проверке на уровне приложения, а не на уровне базы данных.

Другие советы

Начиная с Hibernate 5.1, можно использовать «hibernate.create_empty_composites.enabled» для изменения этого поведения (см. https://hibernate.atlassian.net/browse/HHH-7610 )

Добавьте фиктивное поле в класс с пометкой @Embeddable.

@Formula("0")
private int dummy;

Видеть https://issues.jboss.org/browse/HIBERNATE-50 .

Меня не слишком впечатлило ни одно из ранее сделанных предложений, поэтому я создал аспект, который справится с этим за меня.

Это не полностью протестировано и определенно не проверено на коллекциях встроенных объектов, поэтому будьте осторожны с покупателями.Тем не менее, похоже, у меня пока работает.

По сути, перехватывает метод получения @Embedded поле и гарантирует, что поле заполнено.

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

Вы можете использовать нулевой безопасный геттер.

public Direito getDireito() {
    if (direito == null) {
        direito = new Direito();
    }
    return direito;
}
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top