我正在使用JPA 2.0,更准确地说是Eclipselink。这是我的问题:
我有一个像“isPaid”这样的属性的实体。该属性是实体执行某些其他字段的计算结果。因为这是从其他字段派生的,所以该属性没有setter方法。
举个例子,getter是这样的:
public boolean isPaid() {
return this.totalAmount - this.amountPaid == 0;
}
这只是一个例子。问题是,我想要计算和保持这个属性,所以我可以做一个jpql查询,如:
SELECT d FROM Debt d WHERE d.isPaid = true
这可能吗?有没有解决方法呢?。
我不想检索所有实体来调用此方法,然后过滤那些返回true的实体。
答案 0 :(得分:4)
看到这个:Mapping calculated properties with JPA?
基本上你需要一个setter方式,以使JPA快乐。
答案 1 :(得分:4)
以下是几个选项:
1)创建一个直接执行所需操作的jpql查询:
select d from Debt d where (d.totalAmount - d.amountPaid) = 0
该方法的好处是它很简单并且始终有效。缺点是您的查询必须了解付费逻辑的计算方式。
2)创建一个存储计算值的持久付费值:
@Basic
private boolean paid;
public boolean isPaid() {
return this.paid;
}
private void updateCalculations() {
this.paid = (this.totalAmount - this.amountPaid == 0);
}
// using int as example here
public void setTotalAmount(int totalAmount) {
this.totalAmount = totalAmount;
updateCalculations();
}
public void setAmountPaid(int amountPaid) {
this.amountPaid = amountPaid;
updateCalculations();
}
这种方法的好处是你可以创建一个直接检查布尔值的jpql查询,即
select d from Debt d where d.paid = true;
显然,该方法的缺点是您需要确保在更新值时随时重新计算值。但是,如果您只在访问时计算它,则可以减轻这种情况。这意味着在isPaid()方法中,您计算该值,将其分配给付费属性,然后返回该值。如果您决定采用这种方法,则需要添加一个执行付费计算的@PrePersist和@PreUpdate方法,并在将bean保留到数据存储区之前更新付费属性(确保始终覆盖付费值)
如果您对属性本身使用JPA注释,则可以使用没有setter的getter,并且仍然能够在数据库中正确检索和存储值。