【问题标题】:JPA 2.0 persisting property with no setter没有设置器的 JPA 2.0 持久属性
【发布时间】:2011-06-30 14:20:18
【问题描述】:

我使用的是 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 的实体。

【问题讨论】:

    标签: java orm jpa properties eclipselink


    【解决方案1】:

    这里有几个选项:

    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,并且仍然能够正确检索值并将其存储在数据库中。

    【讨论】:

      【解决方案2】:

      看到这个:Mapping calculated properties with JPA

      基本上,为了让 JPA 满意,您需要一种或另一种方式的 setter。

      【讨论】:

      • 如果我添加一个无操作私有设置器,它会按预期工作吗?对此有什么建议吗?可能有更好的建模方法
      • @arg20 它将正常工作。我不知道 JPA 是否允许只写属性(你真正想要的),但我非常怀疑。所以你最好的选择是欺骗它:)。
      猜你喜欢
      • 2012-07-26
      • 2013-11-05
      • 2021-02-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-03-13
      相关资源
      最近更新 更多