Propiedad calculada con JPA / Hibernate

Mi bean Java tiene una propiedad childCount. Esta propiedad no está asignada a una columna de base de datos . En cambio, debe ser calculado por la base de datos con una función COUNT() que opera en la combinación de mi bean Java y sus hijos. Sería aún mejor si esta propiedad se pudiera calcular según demanda / “perezosamente”, pero esto no es obligatorio.

En el peor de los casos, puedo establecer la propiedad de este bean con HQL o la API Criteria, pero preferiría no hacerlo.

La anotación Hibernate @Formula puede ayudar, pero apenas pude encontrar documentación.

Cualquier ayuda muy apreciada. Gracias.

JPA no ofrece ningún soporte para la propiedad derivada, por lo que deberá usar una extensión específica del proveedor. Como mencionaste, @Formula es perfecto para esto cuando usas Hibernate. Puedes usar un fragmento de SQL:

 @Formula("PRICE*1.155") private float finalPrice; 

O incluso consultas complejas en otras tablas:

 @Formula("(select min(o.creation_date) from Orders o where o.customer_id = id)") private Date firstOrderDate; 

Donde id es la id de la entidad actual.

La siguiente publicación de blog vale la pena leer: Propiedades derivadas de Hibernate: rendimiento y portabilidad .

Sin más detalles, no puedo dar una respuesta más precisa, pero el enlace de arriba debería ser útil.

Ver también:

  • Sección 5.1.22. Elementos de columna y fórmula (documentación de Hibernate Core)
  • Sección 2.4.3.1. Fórmula (documentación de Hibernate Annotations)

Como se explica en este artículo , tiene tres opciones:

  • o bien está calculando el atributo utilizando un método @Transient
  • también puedes usar @PostLoad entity listener
  • o puede usar la anotación @Formula específica de Hibernate

Mientras que Hibernate le permite usar @Formula , con JPA, puede usar la callback @PostLoad para rellenar una propiedad transitoria con el resultado de algún cálculo:

 @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; } 

Para consultas más complejas, puede usar la @Formula Hibernate @Formula , como se explica en este artículo :

 @Formula( "round(" + " (interestRate::numeric / 100) * " + " cents * " + " date_part('month', age(now(), createdOn)" + ") " + "/ 12) " + "/ 100::numeric") private double interestDollars;