有没有办法使用JPA映射计算属性?
假设我有一个Invoice
个对象,其中包含一个或多个InvoiceLineItems
,我想在Invoice
类上有一个持久的计算属性,它给出了总量:
class Invoice {
...
@Column(name = "TOTAL_AMOUNT")
public BigDecimal getTotalAmount() {
BigDecimal amount = BigDecimal.ZERO;
for (InvoiceLineItem lineItem : lineItems) {
amount = amount.add(lineItem.getTotalAmount());
}
return amount;
}
}
现在,我可以创建一个受保护的无操作setTotalAmount
方法来让JPA高兴,但我想知道是否有办法让JPA知道映射只是一种方式,并避免创建多余的setter方法。
谢谢, 阿莱克斯
答案 0 :(得分:9)
您所描述的不是JPA意义上的计算属性。您在自己的方法中自己计算 - 只需将该方法标记为@Transient
,JPA将忽略它。
如果您确实需要计算属性(其中“计算”表示“通过SQL表达式计算”),则需要根据JPA提供程序对其进行注释。对于Hibernate,您可以通过@Formula
注释执行此操作:
@Formula("col1 * col2")
public int getValue() {
...
}
其他提供商可能有自己的方式来配置它;没有JPA标准。
答案 1 :(得分:5)
我知道我正在破坏这个帖子,但也许它可能有助于某人。
如果要计算读取值,@PostLoad
注释可能是您想要的:
@Transient
private BigDecimal totalAmount;
@PostLoad
public void onPostLoad() {
BigDecimal amount = BigDecimal.ZERO;
for (InvoiceLineItem lineItem : lineItems) {
amount = amount.add(lineItem.getTotalAmount());
}
this.totalAmount = amount;
}
答案 2 :(得分:4)
也许PrePersist注释可以用于此。
@Column(name = "TOTAL_AMOUNT")
private BigDecimal totalAmount;
@PrePersist
public void updateTotalAmount() {
BigDecimal amount = BigDecimal.ZERO;
for (InvoiceLineItem lineItem : lineItems) {
amount = amount.add(lineItem.getTotalAmount());
}
this.totalAmount = amount;
}