2009-08-24 41 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

相關問題