我使用的是 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 的实体。
最佳答案
这里有几个选项:
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();
}
这种方法的好处是您将能够创建一个直接检查 boolean 值的 jpql 查询,即
select d from Debt d where d.paid = true;
显然,该方法的缺点是您需要确保在更新值时重新计算值。但是,如果您仅在访问时计算它,则可以缓解这种情况。这意味着在您的 isPaid() 方法中,您计算值,将其分配给付费属性,然后返回该值。如果您决定采用这种方法,您将需要添加一个@PrePersist 和@PreUpdate 方法来执行付费计算并在将 bean 持久保存到数据存储之前更新付费属性(确保付费值始终被覆盖) .
如果您在自己的属性上使用 JPA 注释,您可以拥有一个没有 setter 的 getter,并且仍然能够正确地检索值并将值存储在数据库中。
关于java - 没有 setter 的 JPA 2.0 持久属性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5054747/