Можно ли сделать встроенный объект Hibernate ненулевым? - PullRequest
32 голосов
/ 24 августа 2009

Что я хочу:

@Embedded(nullable = false)
private Direito direito;

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

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

Ответы [ 5 ]

36 голосов
/ 24 августа 2009

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

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

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

16 голосов
/ 02 сентября 2016

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

11 голосов
/ 10 марта 2011

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

@Formula("0")
private int dummy;

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

1 голос
/ 08 июля 2014

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

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

По сути, перехватывает геттер в поле @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;
    }
}
0 голосов
/ 24 октября 2014

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

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