我有一个具有默认值和计算字段的实体,如下所示:
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加载实体时,都会调用setter并在calc中抛出NullPointerException。 无论如何都要在JPA调用setter之前默认值?
答案 0 :(得分:5)
首先,根据您的映射,JPA引擎根本不应该调用setter,因为您通过在字段上放置注释来选择字段访问。
其次,代码中没有total
字段。
第三,该字段根本不存在,因为它可以从另外两个字段计算。只需让其他类调用calcTotal()
即可访问其值。并重命名此方法getTotal()
。
哦,这些字段应该是私密的,而不是公开的。
如果你真的想存储结果以便重用,那么就懒惰地计算它,并在修改其中一个操作数时将其重置为null:
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;
}