Is there a way to externalize HQL named queries to an external file. I have too many named queries and using @NamedQueries
and @NamedQuery
at the head of my entities classes is hurting.
Is there a way to externalize to several files?
Is there a way to externalize HQL named queries to an external file. I have too many named queries and using @NamedQueries
and @NamedQuery
at the head of my entities classes is hurting.
Is there a way to externalize to several files?
You can put the queries into package-info.java
class, in, say, root package of your domain objects. However, you must use Hibernate's own @NamedQueries
and @NamedQuery
annotations, rather than those from javax.persistence
.
Example package-info.java
file:
@org.hibernate.annotations.NamedQueries({
@org.hibernate.annotations.NamedQuery(
name = "foo.findAllUsers",
query="from Users")
})
package com.foo.domain;
Then, you have to add the package to your AnnotationConfiguration
. I use Spring, so there it's a matter of setting annonatedPackages
property:
<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>
You can also put type and filter definitions in the same file as well.
I don't think that this is possible as Annotation attribute/property values must be available at compile time. Therefore, Strings cannot be externalized to a file that needs to be read in by some sort of process.
I tried to find if there was something that package-info.java might be able to provide, but could not find anything.
An alternative strategy for organization could be storing the queries as constants in a Class.
In your entity class:
@NamedQuery(name="plane.getAll", query=NamedQueries.PLANE_GET_ALL)
Then define a class for your query constants:
public class NamedQueries {
...
public static final String PLANE_GET_ALL = "select p from Plane p";
...
}
Maybe this is not exactly what author asked for (to externalize to non-java file), but this is how I solved it:
1.) in my application context xml file I added mappingResources
to 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>
and in that Country.hbm.xml I have
<?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>
I used that just to define named queries, the rest of entity configuration is in annotations.
Maybe that helps someone.
<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>