2012-01-23 10 views
1

私は、デフォルト値を持つエンティティと次のように計算されたフィールドいる:エンティティがJPAによってロードされるたびしかし、セッターはJPAエンティティ既定値

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(); 
    } 
} 

と呼ばれ、NullPointerExceptionがCALCにスローされます。 JPAがセッターを呼び出す前に値をデフォルト設定する必要はありますか?

答えて

5

まず、マッピングを指定すると、アノテーションをフィールドに配置してフィールドアクセスを選択したため、JPAエンジンはセッターをまったく呼び出すべきではありません。

第2に、totalフィールドにコードがありません。

第3に、このフィールドは、他の2つのフィールドから計算できるため、存在してはいけません。その値にアクセスするために他のクラスに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; 
} 
+0

私は不足している分野の合計でコードを編集しました。私は、プレイフレームワークがJPAを強化し、ゲッター/セッターが存在しない場合はそれを追加すると信じています。フィールドは公開される必要があります。この考え方は、値の1つが更新されたときにのみ合計を計算することであり、合計が必要なときは常に計算されません。 – emt14

+1

Playがエンティティのコードを完全に変更しない限り、私のポイントはまだ残っています。最初にセッターにアクセスすべきではありません。そして、あなたが合計をマップしたやり方では、それはデータベースに残っています。これは全く必要ではありません。そして、追加のコストは、データベースからエンティティをロードするコストに比べてばかげて無視できるものです。それぞれのアクセスでそれを計算しても、大きな違いはありません。 –

+0

合計の永続性についての良い点は、私はそれを一時的にします。しかし、これは単純な例であり、私の場合はこれが理にかなっています。 – emt14

関連する問題