내 Java bean에는 childCount 속성이 있습니다. 이 속성은 데이터베이스 열에 매핑되지 않습니다 . 대신, 내 Java bean과 그 자식의 조인에서 작동 하는 COUNT()
함수 를 사용하여 데이터베이스에서 계산 해야합니다 . 이 속성을 요청시 / “게으르게”계산할 수 있다면 더 좋겠지 만 필수는 아닙니다.
최악의 시나리오에서는 HQL 또는 Criteria API를 사용하여이 빈의 속성을 설정할 수 있지만 선호하지 않습니다.
Hibernate @Formula
주석이 도움이 될 수 있지만 문서를 거의 찾을 수 없습니다.
어떤 도움이라도 대단히 감사합니다. 감사.
답변
JPA는 파생 속성에 대한 지원을 제공하지 않으므로 공급자 별 확장을 사용해야합니다. 당신이 언급했듯이, @Formula
Hibernate를 사용할 때 이것에 완벽합니다. SQL 조각을 사용할 수 있습니다.
@Formula("PRICE*1.155")
private float finalPrice;
또는 다른 테이블에 대한 복잡한 쿼리 :
@Formula("(select min(o.creation_date) from Orders o where o.customer_id = id)")
private Date firstOrderDate;
현재 엔티티 id
는 어디에 있습니까 id
?
다음 블로그 게시물은 읽을 가치가 있습니다 : Hibernate Derived Properties-Performance and Portability .
자세한 내용이 없으면 더 정확한 답변을 드릴 수 없지만 위 링크가 도움이 될 것입니다.
또한보십시오:
답변
이 도움말에 설명 된대로 세 가지 옵션이 있습니다.
@Transient
방법을 사용하여 속성을 계산하거나@PostLoad
엔티티 리스너 를 사용할 수도 있습니다.- 또는 Hibernate 특정
@Formula
주석을 사용할 수 있습니다.
최대 절전 모드를 사용할 수 있지만 @Formula을 JPA와 함께, 당신은 사용할 수 있습니다 @PostLoad의 채우는 콜백을 과도 약간의 계산 결과와 속성을 :
@Column(name = "price")
private Double price;
@Column(name = "tax_percentage")
private Double taxes;
@Transient
private Double priceWithTaxes;
@PostLoad
private void onLoad() {
this.priceWithTaxes = price * taxes;
}
더 복잡한 쿼리의 경우이 기사@Formula
에서 설명한대로 Hibernate를 사용할 수 있습니다 .
@Formula(
"round(" +
" (interestRate::numeric / 100) * " +
" cents * " +
" date_part('month', age(now(), createdOn)" +
") " +
"/ 12) " +
"/ 100::numeric")
private double interestDollars;
답변
JPA 위에서 작동하고 일류 DTO 지원을 제공하는 Blaze-Persistence Entity Views 를 살펴보십시오 . 엔티티 뷰 내의 속성에 무엇이든 프로젝션 할 수 있으며 가능한 경우 기존 조인 노드를 다시 사용하여 연관시킬 수도 있습니다.
다음은 매핑의 예입니다.
@EntityView(Order.class)
interface OrderSummary {
Integer getId();
@Mapping("SUM(orderPositions.price * orderPositions.amount * orderPositions.tax)")
BigDecimal getOrderAmount();
@Mapping("COUNT(orderPositions)")
Long getItemCount();
}
이것을 가져 오면 다음과 유사한 JPQL / HQL 쿼리가 생성됩니다.
SELECT
o.id,
SUM(p.price * p.amount * p.tax),
COUNT(p.id)
FROM
Order o
LEFT JOIN
o.orderPositions p
GROUP BY
o.id
다음은 사용자에게 흥미로울 수있는 사용자 지정 하위 쿼리 공급자에 대한 블로그 게시물입니다. https://blazebit.com/blog/2017/entity-view-mapping-subqueries.html
답변
나는 내 코드에서 이것을 시도했다.
@Formula(value = "(select DATEDIFF(expiry_date,issue_date) from document_storage)")
private String myColumn;
콧수염에 열을 표시하기 전에도 실행하고 내 뷰를 표시 할 때 발생하는 오류는 다음과 같습니다.
java.lang.NullPointerException
at java.base/java.lang.String$CaseInsensitiveComparator.compare(String.java:1241)
at java.base/java.lang.String$CaseInsensitiveComparator.compare(String.java:1235)
at java.base/java.util.TreeMap.getEntryUsingComparator(TreeMap.java:374)
at java.base/java.util.TreeMap.getEntry(TreeMap.java:343)
at java.base/java.util.TreeMap.get(TreeMap.java:277)
at com.mysql.cj.result.DefaultColumnDefinition.findColumn(DefaultColumnDefinition.java:182)
내가 묻는 질문은 mySQL과 함께 JPA / Hibernate를 사용하여 계산 된 열의 값을 얻는 방법이 있습니까?
내가 뭘 잘못하고 있죠 ?