Meine Java-Bean verfügt über eine childCount-Eigenschaft. Diese Eigenschaft ist einer Datenbankspalte nicht zugeordnet. Stattdessen sollte es von der Datenbank mit einer COUNT()
-Funktion berechnet werden, die auf den Join meiner Java-Bean und ihrer untergeordneten Elemente angewendet wird. Es wäre noch besser, wenn diese Eigenschaft auf Nachfrage/"faul" berechnet werden könnte, dies ist jedoch nicht zwingend.
Im schlimmsten Fall kann ich die Eigenschaft dieser Bean mit HQL oder der Criteria API festlegen, aber ich würde es nicht vorziehen.
Die Hibernate @Formula
-Anmerkung kann hilfreich sein, aber ich konnte kaum Dokumentation finden.
Jede Hilfe sehr geschätzt. Vielen Dank.
JPA bietet keine Unterstützung für abgeleitete Eigenschaften, daher müssen Sie eine anbieterspezifische Erweiterung verwenden. Wie Sie bereits erwähnt haben, ist @Formula
ideal, wenn Sie Hibernate verwenden. Sie können ein SQL-Fragment verwenden:
@Formula("PRICE*1.155")
private float finalPrice;
Oder auch komplexe Abfragen zu anderen Tabellen:
@Formula("(select min(o.creation_date) from Orders o where o.customer_id = id)")
private Date firstOrderDate;
Wobei id
die id
der aktuellen Entität ist.
Der folgende Blogbeitrag ist das Lesen wert: Hibernate Abgeleitete Eigenschaften - Leistung und Portabilität .
Ohne weitere Details kann ich keine genauere Antwort geben, aber der obige Link sollte hilfreich sein.
Wie in diesem Artikel erklärt, haben Sie drei Möglichkeiten:
@Transient
-Methode@PostLoad
-Entitätenlistener verwenden@Formula
-Anmerkung verwendenMit Hibernate können Sie @Formula mit JPA verwenden. Mit dem @PostLoad - Callback können Sie eine transient - Eigenschaft mit dem Ergebnis einiger Berechnungen füllen:
@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;
}
Für komplexere Abfragen können Sie den Hibernate @Formula
verwenden, wie in diesem Artikel erläutert:
@Formula(
"round(" +
" (interestRate::numeric / 100) * " +
" cents * " +
" date_part('month', age(now(), createdOn)" +
") " +
"/ 12) " +
"/ 100::numeric")
private double interestDollars;
Werfen Sie einen Blick auf Blaze-Persistence Entity Views , das auf JPA aufbaut und erstklassigen DTO-Support bietet. Sie können Attribute in Entity Views projizieren, und vorhandene Verknüpfungsknoten werden nach Möglichkeit sogar für Verknüpfungen verwendet.
Hier ist ein Beispiel für ein Mapping
@EntityView(Order.class)
interface OrderSummary {
Integer getId();
@Mapping("SUM(orderPositions.price * orderPositions.amount * orderPositions.tax)")
BigDecimal getOrderAmount();
@Mapping("COUNT(orderPositions)")
Long getItemCount();
}
Durch das Abrufen dieses Befehls wird eine ähnliche JPQL/HQL-Abfrage generiert
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
Hier ist ein Blog-Post über Anbieter von benutzerdefinierten Unterabfragen, die für Sie ebenfalls interessant sein könnten: https://blazebit.com/blog/2017/entity-view-mapping-subqueries.html