2009-08-31 6 views
11

JPA를 사용하여 계산 된 속성을 매핑하는 방법이 있습니까?JPA로 계산 된 속성 매핑

내가 그 안에 하나 또는 그 이상의 InvoiceLineItems와 함께 Invoice 개체가 가정, 내가 나에게 총 금액주는 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; 
    } 
} 

을, 나는를 만들 수 있습니다 protected no-op setTotalAmount JPA를 행복하게 만드는 방법이지만, JPA에 매핑이 한 가지 방법 일 뿐이고 불필요한 setter 메서드를 만들지 않도록하는 방법이 있는지 궁금합니다.

감사합니다, 하기 Aleks

답변

9

당신이 설명한 것은 JPA의 의미에서 계산 된 재산이 아니다. 메소드 내에서 직접 계산하고 있습니다.이 메소드를 @Transient으로 표시하면 JPA가이를 무시합니다.

"계산 된"은 "SQL 식을 통해 계산 된"을 의미하는 계산 된 속성이 정말로 필요한 경우 JPA 공급자에 따라 주석을 추가해야합니다.

@Formula("col1 * col2") 
public int getValue() { 
... 
} 

다른 공급자가이를 구성하는 자신의 방법이있다 : 최대 절전 모드를 들어 당신은 @Formula 주석을 통해 그렇게 할 것 JPA 표준은 없습니다.

+0

표시 속성은 나에게 도움이되지 않습니다 : 당신이 읽기에 값을 계산하려면

@PostLoad 주석 당신이 원하는 수 있습니다. JPA가 그것을 무시하지 않기를 바란다. 총계를 데이터베이스에 저장하여 자식 테이블의 정보를 집계하지 않고도 직접 쿼리 할 수 ​​있기를 바란다. 그래서 저는 불필요한 setter를 구현하지 않고 계산 된 속성 (Java 의미에서 완전성과 완전히 무관)을 유지하는 방법을 묻습니다. –

+3

당신의 예는 다소 이상합니다. **이 값을 저장하고 쿼리하는 경우 왜 getter에서 다시 계산합니까? 그러나 요점은 JPA가 엔티티에서 해당 값을 채우도록하기 위해 getter 메소드에 주석을 달려면 (속성과 대비하여) 해당 setter가 있어야한다는 것입니다. – ChssPly76

+0

내가 준 예제는 일하고있는 도메인 모델의 과도한 단순화입니다.이 모델은 일대 다 관계의 여러 수준을 가지고 있으며, 각 수준에서 계산 된 속성을 자식에 의존합니다. 필요에 따라 Java에서 값을 계산하는 것이 (깊은) 계층 구조의 하위 개체가 추가, 제거 또는 수정 될 때 총계를 업데이트하는 것보다 훨씬 쉽습니다. 따라서 다시 계산합니다. –

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; 
} 
+0

감사합니다. 알겠습니다. 감사합니다. 그러나 총계가 업데이트 될 때마다 그것을 볼 때마다 기다릴 필요가 없습니다. 특정 상황에서는 작동하지 않을 것입니다. –

+0

Braaaains ... 내 말은, 왜 당신이 비공개'updateTotalAmount)'메소드를 호출하고,'getTotalAmount()'acccessor와'@ PrePersist'에서 호출하는 것인가? getter는 무엇을위한 것이 아닌가? –

5

나는이 스레드를 괴롭히는 것을 알고 있지만 누군가가 도움이 될 수도 있습니다. @Transient로

@Transient 
private BigDecimal totalAmount; 

@PostLoad 
public void onPostLoad() { 
    BigDecimal amount = BigDecimal.ZERO; 
    for (InvoiceLineItem lineItem : lineItems) { 
     amount = amount.add(lineItem.getTotalAmount()); 
    } 
    this.totalAmount = amount; 
} 
+1

OP 질문에 대한 대답이 아니지만 우연히, 내가 OP와 약간 다른 것을 원할 때 나의 질문에 대답해라. .. 여기에 그것을 게시하는 것에 대해 고마워! +1 –

관련 문제