Как мне экстернализировать именованные запросы в приложении Hibernate annotations?
Вопрос
Есть ли способ экстернализировать именованные запросы HQL во внешний файл?У меня слишком много именованных запросов, и я использую @NamedQueries
и @NamedQuery
во главе моих классов сущностей стоит боль.
Есть ли способ выполнить экстернализацию для нескольких файлов?
Решение
Вы можете поместить запросы в package-info.java
класс, скажем, в корневом пакете объектов вашего домена.Однако вы должны использовать собственный Hibernate @NamedQueries
и @NamedQuery
аннотации, а не те, что из javax.persistence
.
Пример package-info.java
файл:
@org.hibernate.annotations.NamedQueries({
@org.hibernate.annotations.NamedQuery(
name = "foo.findAllUsers",
query="from Users")
})
package com.foo.domain;
Затем вы должны добавить пакет в свой AnnotationConfiguration
.Я использую Spring, так что там все зависит от настройки 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>
Вы также можете поместить определения типов и фильтров в один и тот же файл.
Другие советы
Я не думаю, что это возможно, поскольку значения атрибутов аннотации / свойств должны быть доступны во время компиляции.Следовательно, строки не могут быть экстернализованы в файл, который должен быть прочитан каким-либо процессом.
Я попытался найти, есть ли что-нибудь, что package-info.java могло бы быть в состоянии предоставить, но ничего не смог найти.
Альтернативной стратегией организации могло бы быть хранение запросов в виде констант в классе.
В вашем классе сущностей:
@NamedQuery(name="plane.getAll", query=NamedQueries.PLANE_GET_ALL)
Затем определите класс для констант вашего запроса:
public class NamedQueries {
...
public static final String PLANE_GET_ALL = "select p from Plane p";
...
}
Возможно, это не совсем то, о чем просил автор (для экстернализации в файл, отличный от java), но именно так я это решил:
1.) в XML-файл контекста моего приложения я добавил mappingResources
к 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>
и в этом Country.hbm.xml у меня есть
<?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>
Я использовал это только для определения именованных запросов, остальная часть конфигурации объекта находится в аннотациях.
Может быть, это кому-то поможет.
<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>