2009-08-24 53 views
27

我想要什么:我可以使嵌入式Hibernate实体不可空吗?

@Embedded(nullable = false) 
private Direito direito; 

然而,正如你知道有没有这样的属性@Embeddable。

有没有正确的方法来做到这一点?我不想要解决方法。

+0

你的意思是一个复合元素? – Zoidberg 2009-08-24 19:35:27

+0

是的。为什么我的答案少于15个字? – 2009-08-24 19:46:14

+0

我不知道如何做注释,但我可以告诉你xml – Zoidberg 2009-08-24 19:51:58

回答

33

可嵌入组件(或复合元素,无论您想调用它们)通常包含多个属性,因此映射到多个列。因此可以用不同的方式处理整个零部件; J2EE规范并没有规定这种或那种方式。

如果Hibernate的所有属性都为NULL(反之亦然),则认为该组件为NULL。因此,您可以声明一个(任何)属性不为空(在@Embeddable内或作为@Embedded@AttributeOverride的一部分)以实现您想要的效果。

或者,如果您使用的是Hibernate Validator,则可以使用@NotNull注释您的属性,但这只会导致应用程序级别的检查,而不会导致数据库级别的检查。

+0

+1,很好的答案 – skaffman 2009-08-24 19:57:29

+0

谢谢!将@Nullable添加到组合的属性。 – 2009-08-25 18:43:07

+0

不适用于我。如果'@ Embeddable'只有一个字段,用'@Access(AccessType.FIELD)'注解''有问题吗? – 2013-04-18 13:06:47

11

将哑元字段添加到标记为@Embeddable的类中。

@Formula("0") 
private int dummy; 

请参阅https://issues.jboss.org/browse/HIBERNATE-50

+0

它仍然适合你吗?对我而言,它不... – 2013-04-18 13:01:56

+0

它与Hibernate 3.5.3-Final一起工作。 – adam0404 2014-03-04 18:50:53

+0

Hibernate 4.3.7.Final不适用于我(尝试了几个类似的东西,都没有工作) – NoUsername 2015-01-30 10:54:34

1

我对之前提出的任何建议都不太满意,所以我创建了一个方面来处理这个问题。

这没有完全测试,并且绝对没有针对嵌入对象的集合进行测试,所以买方要小心。但是,迄今为止似乎对我有用。

基本上,将获取者拦截到@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; 
    } 
} 
1

您可以使用nullsafe getter。

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

请注意,这将导致您的实体在每次读取时都被标记为脏,从而导致Hibernate增加版本。这将导致乐观锁定异常。 – Arlo 2014-11-27 12:53:24

+0

该解决方案触发数据库服务器的sql更新指令,带来线程间并发性和性能问题等问题。 – 2015-03-05 03:36:40

相关问题