我想要的是什么:
@Embedded(nullable = false)
private Direito direito;
但是,正如你所知,@ Embeddable没有这样的属性。
有没有正确的方法呢?我不想要解决方法。
答案 0 :(得分:36)
可嵌入组件(或复合元素,无论您想要调用它们)通常包含多个属性,因此映射到多个列。因此可以以不同的方式处理整个组件为空; J2EE规范并没有这样或那样的方式。
如果组件的所有属性都为NULL,则Hibernate认为组件为NULL(反之亦然)。因此,您可以声明一个(任何)属性不为空(在@Embeddable
内或@AttributeOverride
上@Embedded
的一部分),以实现您想要的目标。
或者,如果您正在使用Hibernate Validator,则可以使用@NotNull
注释您的属性,尽管这只会导致应用级检查,而不是数据库级别。
答案 1 :(得分:16)
从Hibernate 5.1开始,可以使用“hibernate.create_empty_composites.enabled”来改变这种行为(参见https://hibernate.atlassian.net/browse/HHH-7610)
答案 2 :(得分:11)
将虚拟字段添加到标记为@Embeddable。
的类中@Formula("0")
private int dummy;
答案 3 :(得分:1)
我对以前提出的任何建议都不太兴奋,所以我创建了一个方面来处理这个问题。
这尚未经过全面测试,并且绝对没有针对嵌入式对象的集合进行测试,所以买家要小心。但是,到目前为止似乎对我有用。
基本上,拦截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;
}
}
答案 4 :(得分:0)
您可以使用nullsafe getter。
public Direito getDireito() {
if (direito == null) {
direito = new Direito();
}
return direito;
}