Подтвердить что ты не робот

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

Что я хочу:

@Embedded(nullable = false)
private Direito direito;

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

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

4b9b3361

Ответ 1

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

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

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

Ответ 4

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

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

В основном, перехватывает getter в поле @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;
    }
}

Ответ 5

Вы можете использовать получатель nullsafe.

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