2012-01-23 145 views
1

我與默認值和計算的字段的實體如下:JPA實體默認值

public class Target{ 
    @Transient 
    public Long  total; 

    @Min(0) 
    @Column(columnDefinition="default 0") 
    public Long  val1 = 0L; 
    @Min(0) 
    @Column(columnDefinition="default 0") 
    public Long  val2 = 0L; 

    public Target() { 
     this.total = Long.valueOf(0L); 
     this.val1 = Long.valueOf(0L); 
     this.val2 = Long.valueOf(0L); 
    } 

    public Long calcTotal() { 
     return val1 + val2 ; 
    } 

    public void setVal1(Long val) { 
     this.val1 = checkNotNull(val); 
     total = calcTotal(); 
    } 

    public void setVal2(Long val) { 
     this.val2 = checkNotNull(val); 
     total = calcTotal(); 
    } 
} 

然而每當實體由JPA加載,設置器被稱爲和一個NullPointerException在計算值拋出。 在JPA調用setter之前是否有默認值?

回答

5

首先,根據您的映射,JPA引擎根本不應該調用setter,因爲您通過將註釋放在字段上來選擇字段訪問。

二,代碼中沒有total字段。

第三,這個字段根本不應該存在,因爲它可以從兩個其他字段計算出來。讓其他職業電話撥打calcTotal()即可獲得其價值。並重命名此方法getTotal()

哦,這些字段應該是私有的,不公開的。

如果你真的想保存再利用的結果,然後計算它懶洋洋地,當一個操作數被修改重置爲空:

public Long getTotal() { 
    if (total == null) { 
     total = val1 + val2; 
    } 
    return total; 
} 

public void setVal1(Long val1) { 
    this.val1 = val1; 
    this.total = null; 
} 

public void setVal2(Long val2) { 
    this.val2 = val2; 
    this.total = null; 
} 
+0

我編輯的代碼與失蹤總場。我相信play framework增強了JPA,並且增加了getter/setter(如果不存在的話)。這些字段需要公開。這個想法是隻計算一次數值更新時的總數,而不是每次需要總數。 – emt14

+1

除非Play完全改變實體的代碼,否則我的觀點仍然存在:不應該首先訪問setters。而且你已經完成了映射的方式,它仍然存在於數據庫中,這根本不是必需的。與從數據庫中加載實體的成本相比,加法的成本是可笑且可以忽略的。在每次訪問時計算它並不會產生任何顯着差異。 –

+0

關於總體持久性的好處,我會讓它變成一時的。然而,這是一個簡單的例子,在我的特殊情況下,這是有道理的。 – emt14