Java Beanには、childCountプロパティがあります。このプロパティはデータベース列にマップされていないです。代わりに、COUNT()
関数を使用してデータベースで計算 Java Beanとその子の結合で操作する必要があります。このプロパティをオンデマンドで/「怠 "に」計算できればさらに良いでしょうが、これは必須ではありません。
最悪のシナリオでは、このBeanのプロパティを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 。
詳細がなければ、より正確な答えを出すことはできませんが、上記のリンクは役に立つはずです。
この記事 で説明されているように、3つのオプションがあります。
@Transient
メソッドを使用して属性を計算するか、@PostLoad
エンティティリスナーを使用することもできます@Formula
アノテーションを使用できますHibernateではJPAで @ Formula を使用できますが、 @ PostLoad コールバックを使用してtransient何らかの計算の結果を持つプロパティ:
@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;
}
より複雑なクエリの場合は、 この記事 で説明されているように、Hibernate @Formula
を使用できます。
@Formula(
"round(" +
" (interestRate::numeric / 100) * " +
" cents * " +
" date_part('month', age(now(), createdOn)" +
") " +
"/ 12) " +
"/ 100::numeric")
private double interestDollars;
Blaze-Persistence Entity Views を見てください。これはJPAの上で動作し、ファーストクラスのDTOサポートを提供します。エンティティビュー内の属性には何でも投影でき、可能な場合は既存の結合ノードを関連付けに再利用します。
マッピングの例を次に示します
@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