20

I'm trying to put my named queries in my orm.xml (put in META-INF with persistence.xml) but my orm.xml seems to be ignored by hibernate/jpa.

When I try to create my named query with em.createNamedQuery("myQuery"), it returns that it can't find this query.

I use annotation and I would like to externalize my named queries in orm.xml (only that).

Here is my persistence.xml:

<?xml version="1.0" encoding="UTF-8"?>
<persistence xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd" version="1.0">

<persistence-unit name="default" transaction-type="RESOURCE_LOCAL">
    <mapping-file>META-INF/orm.xml</mapping-file>

    <class>com.mysite.Account</class>

    <properties>
        <property name="hibernate.cache.provider_class" value="net.sf.ehcache.hibernate.EhCacheProvider" />
        <property name="hibernate.cache.use_query_cache" value="true" />
        <property name="hibernate.cache.use_second_level_cache" value="true" />
        <property name="hibernate.show_sql" value="true" />
        <property name="hibernate.format_sql" value="true" />
        <property name="use_sql_comments" value="false" />
        <property name="hibernate.dialect" value="org.hibernate.dialect.MYSQLDialect" />
        <property name="hibernate.c3p0.min_size" value="5" />
        <property name="hibernate.c3p0.max_size" value="20" />
        <property name="hibernate.c3p0.timeout" value="300" />
        <property name="hibernate.c3p0.max_statements" value="50" />
        <property name="hibernate.c3p0.idle_test_period" value="3000" />

        <property name="hibernate.search.default.directory_provider" value="org.hibernate.search.store.FSDirectoryProvider" />
    </properties>

</persistence-unit>

</persistence>

here is my orm.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_1_0.xsd" version="1.0">

<package>com.mysite</package>

<entity class="Account">
    <sql-result-set-mapping name="nicknames">
        <column-result name="nickname" />
    </sql-result-set-mapping>
    <table name="Account" />
    <named-native-query name="myQuery" result-set-mapping="nicknames">
        <query><![CDATA[select a.nickname from Account a]]>
    </query>
    </named-native-query>
</entity>
</entity-mappings>

What I'm doing wrong ? Why my orm.xml is ignored ?

thanks

Betlista
  • 10,327
  • 13
  • 69
  • 110
Jerome Cance
  • 8,103
  • 12
  • 53
  • 106

4 Answers4

11

Ok I finally got it !

I was saving my orm.xml in META-INF directory. When I move this file to my package where I have my domain object (like in my example: com.mysite), the orm.xml is not ignored and all run.

I also need to change the path in mapping-file (persistence.xml) : com/mysite/orm.xml

Jerome Cance
  • 8,103
  • 12
  • 53
  • 106
5

Your orm.xml has a minor error in it that breaks the whole thing. The point is that the sequence of elements' declarations should comply with the respective XML schema (which is http://java.sun.com/xml/ns/persistence/orm_1_0.xsd in particular). That is easy to check by running the xml code through a validator which honours xml schemas. Below is the corrected version of your orm.xml that must work as a charm.

<?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_1_0.xsd"
                 version="1.0">

    <package>com.mysite</package>

    <entity class="Account">
        <table name="Account" />
        <named-native-query name="myQuery" result-set-mapping="nicknames">
            <query><![CDATA[
            select a.nickname from Account a
            ]]></query>
        </named-native-query>
        <sql-result-set-mapping name="nicknames">
            <column-result name="nickname" />
        </sql-result-set-mapping>
    </entity>
</entity-mappings>
Betlista
  • 10,327
  • 13
  • 69
  • 110
Dmitri
  • 93
  • 1
  • 5
2

As said

When I try to create my named query with em.createNamedQuery("myQuery"), it returns that it can not find this query.

You are right. But you forget the following

If you place a named query definition inside a element, instead of the root, it is prefixed with the name of the entity class

So you need to call your namedQuery as

 em.createNamedQuery("Account.myQuery")

I am curious: Does your Account class is stored in the root classpath ??? If not, you have fix its missing package. Suppose Account class is stored inside br.com.hibernate.model.domain.Account. So you should declare your entity as

<entity class="br.com.hibernate.model.domain.Account" instead

And you need to call your namedQuery as

em.createNamedQuery("br.com.hibernate.model.domain.Account.myQuery") instead

Just an adivice: when you are using Hibernate as your Persistence Provider, you do not need to define your Entity class in persistence.xml file.

regards,

Arthur Ronald
  • 33,349
  • 20
  • 110
  • 136
  • nice, I suspected something of this sort, but didn't find the explanation in the xsd. Could you link the docs where that is written? Is it the spec? – Bozho Mar 04 '10 at 07:57
  • @Bohzo Ok, Bohzo. Java Persistence with Hibernate book: Defining a named query in XML metadata. Besides that, JPA specification talks about it. – Arthur Ronald Mar 04 '10 at 13:53
  • That does not run. I've tried all solutions. For the complete path name, I was thinking that the package tag was here to specify the default package to use when you named an entity, no ? To simplify, I've also tried to put the named query in the root entity-mappings tag with no result. Like I said, orm.xml is ignored because if I create an error in my xml (no end tag), I've got no error at hibernate startup... – Jerome Cance Mar 04 '10 at 14:34
  • The `` element allows to not use the fully qualified name. – Pascal Thivent Mar 04 '10 at 15:11
0

"META-INF/orm.xml" is the default mapping file that will be looked upon by any JPA compliant entity manager.

In fact, if your mapping file is "META-INF/orm.xml", you need not even define that in your persistence.xml.

This is what the hibernate configuration manual says about this:

The class element specifies a EJB3 compliant XML mapping file that you will map. The file has to be in the classpath. As per the EJB3 specification, Hibernate EntityManager will try to load the mapping file located in the jar file at META_INF/orm.xml. Of course any explicit mapping file will be loaded too. As a matter of fact, you can provides any XML file in the mapping file element ie. either hbm files or EJB3 deployment descriptor.

Reference: Hibernate configuration

James Selvakumar
  • 2,679
  • 1
  • 23
  • 28