¿Cómo externalizo las consultas con nombre en una aplicación de anotaciones de Hibernate?
Pregunta
¿Hay alguna forma de externalizar consultas con nombre HQL a un archivo externo? Tengo demasiadas consultas con nombre y el uso de @NamedQueries
y @NamedQuery
en la cabeza de las clases de mis entidades está haciendo daño.
¿Hay alguna manera de externalizar a varios archivos?
Solución
Puede colocar las consultas en la clase package-info.java
, en, digamos, el paquete raíz de sus objetos de dominio. Sin embargo, debe usar las propias anotaciones @NamedQueries
y @NamedQuery
de Hibernate, en lugar de las de javax.persistence
.
Ejemplo package-info.java
:
@org.hibernate.annotations.NamedQueries({
@org.hibernate.annotations.NamedQuery(
name = "foo.findAllUsers",
query="from Users")
})
package com.foo.domain;
Luego, debe agregar el paquete a su AnnotationConfiguration
. Uso Spring, por lo que se trata de establecer la propiedad annonatedPackages
:
<bean id="sessionFactory"
class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
<property name="annotatedClasses">
<list>
...
</list>
</property>
<property name="annotatedPackages">
<list>
<value>com.foo.domain</value>
</list>
</property>
También puede poner definiciones de tipo y filtro en el mismo archivo también.
Otros consejos
No creo que esto sea posible ya que el atributo de Anotación / valores de propiedad deben estar disponibles en tiempo de compilación. Por lo tanto, las cadenas no se pueden externalizar a un archivo que necesita ser leído por algún tipo de proceso.
Traté de encontrar si había algo que package-info.java pudiera proporcionar, pero no pude encontrar nada.
Una estrategia alternativa para la organización podría ser almacenar las consultas como constantes en una Clase.
En su clase de entidad:
@NamedQuery(name="plane.getAll", query=NamedQueries.PLANE_GET_ALL)
Luego defina una clase para sus constantes de consulta:
public class NamedQueries {
...
public static final String PLANE_GET_ALL = "select p from Plane p";
...
}
Tal vez esto no sea exactamente lo que el autor solicitó (para externalizar a un archivo que no sea Java), pero así es como lo resolví:
1.) en el archivo xml de contexto de mi aplicación agregué mappingResources
a sessionFactory
<bean id="sessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="mappingResources">
<list>
<value>META-INF/Country.hbm.xml</value>
</list>
</property>
<property name="annotatedClasses">
<util:list>
<value>com.example.Country</value>
</util:list>
</property>
<property name="hibernateProperties" ref="hibernateProperties" />
</bean>
y en ese Country.hbm.xml tengo
<?xml version="1.0" encoding="UTF-8"?>
<entity-mappings
xmlns="http://java.sun.com/xml/ns/persistence/orm"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/persistence/orm http://java.sun.com/xml/ns/persistence/orm_2_0.xsd"
version="2.0">
<entity class="com.example.Country">
<named-query name="countryFindByCode">
<query><![CDATA[
select c
from Country c
where c.code = :code
]]></query>
</named-query>
<named-query name="countryFindByName">
<query><![CDATA[
select c
from Country c
where c.name = :name
]]></query>
</named-query>
</entity>
</entity-mappings>
Utilicé eso solo para definir consultas con nombre, el resto de la configuración de la entidad está en anotaciones.
Quizás eso ayude a alguien.
<bean id="sessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="mappingResources">
<list>
<value>META-INF/Country.hbm.xml</value>
</list>
</property>
<property name="annotatedCla
from Country c
where c.name = :name
]]></query>
</named-query>
</entity>
</entity-mappings>