Propiedad calculada con JPA / Hibernate


Mi Java bean tiene una propiedad childCount. Esta propiedad es no asignada a una columna de base de datos. En su lugar, debería ser calculado por la base de datos con una función COUNT() operando en la unión de mi Java bean y sus hijos. Sería aún mejor si esta propiedad pudiera ser calculada bajo 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.

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

Cualquier ayuda muy apreciada. Gracias.

Author: Vlad Mihalcea, 2010-06-07

2 answers

JPA no ofrece soporte para propiedades derivadas, por lo que tendrá que usar una extensión específica del proveedor. Como mencionaste, @Formula es perfecto para esto cuando se usa Hibernate. Puede usar un fragmento 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 id de la entidad actual.

Vale la pena leer la siguiente entrada de blog: Propiedades derivadas de Hibernación - Rendimiento y Portabilidad.

Sin más detalles, no puedo dar una respuesta más precisa, pero el enlace anterior debe ser útil.

Véase también:

 136
Author: Pascal Thivent,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-06-20 16:43:20

Como se explica en este artículo , tienes 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 específica de hibernación @Formula

Mientras que Hibernate le permite usar @ Formula , con JPA, puede usar la devolución de llamada @PostLoad para rellenar una propiedad transient con el resultado de 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 el 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;
 32
Author: Vlad Mihalcea,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-03-27 07:14:25