简体   繁体   English

使用jpa和hibernate在orm.xml中定义命名查询

[英]define named query in orm.xml with jpa and hibernate

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. 我正在尝试将我的命名查询放在我的orm.xml中(使用persistence.xml放入META-INF)但是我的orm.xml似乎被hibernate / jpa忽略了。

When I try to create my named query with em.createNamedQuery("myQuery"), it returns that it can't find this query. 当我尝试使用em.createNamedQuery(“myQuery”)创建我的命名查询时,它返回它无法找到此查询。

I use annotation and I would like to externalize my named queries in orm.xml (only that). 我使用注释,我想在orm.xml中外化我的命名查询(仅限于此)。

Here is my persistence.xml: 这是我的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 这是我的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 ? 为什么我的orm.xml被忽略了?

thanks 谢谢

Ok I finally got it ! 好的,我终于明白了!

I was saving my orm.xml in META-INF directory. 我将我的orm.xml保存在META-INF目录中。 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. 当我将此文件移动到我的域名对象的包中时(如我的示例:com.mysite),orm.xml不会被忽略并且全部运行。

I also need to change the path in mapping-file (persistence.xml) : com/mysite/orm.xml 我还需要更改mapping-file(persistence.xml)中的路径:com / mysite / orm.xml

Your orm.xml has a minor error in it that breaks the whole thing. 你的orm.xml中有一个小错误,它打破了整个事情。 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). 关键是元素的声明序列应该符合相应的XML模式(特别是http://java.sun.com/xml/ns/persistence/orm_1_0.xsd )。 That is easy to check by running the xml code through a validator which honours xml schemas. 通过验证xml架构的验证器运行xml代码很容易检查。 Below is the corrected version of your orm.xml that must work as a charm. 以下是必须作为魅力的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">
        <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>

As said 如上所述

When I try to create my named query with em.createNamedQuery("myQuery"), it returns that it can not find this query . 当我尝试使用em.createNamedQuery(“myQuery”)创建我的命名查询时, 它返回它无法找到此查询

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 所以你需要将你的namedQuery称为

 em.createNamedQuery("Account.myQuery")

I am curious: Does your Account class is stored in the root classpath ??? 我很好奇:您的Account类是否存储在根类路径中? If not, you have fix its missing package. 如果没有,您已修复其缺失的包。 Suppose Account class is stored inside br.com.hibernate.model.domain.Account. 假设Account类存储在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 你需要将namedQuery称为

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. 只是一个adivice:当您使用Hibernate作为持久性提供程序时,您不需要在persistence.xml文件中定义您的Entity类。

regards, 问候,

"META-INF/orm.xml" is the default mapping file that will be looked upon by any JPA compliant entity manager. “META-INF / orm.xml”是任何符合JPA的实体管理器将查看的默认映射文件。

In fact, if your mapping file is "META-INF/orm.xml", you need not even define that in your persistence.xml. 实际上,如果您的映射文件是“META-INF / orm.xml”,则甚至无需在persistence.xml中定义它。

This is what the hibernate configuration manual says about this: 这就是hibernate配置手册对此的说法:

The class element specifies a EJB3 compliant XML mapping file that you will map. class元素指定要映射的符合EJB3的XML映射文件。 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. 根据EJB3规范,Hibernate EntityManager将尝试加载位于META_INF / orm.xml的jar文件中的映射文件。 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. 事实上,您可以在映射文件元素中提供任何XML文件,即。 either hbm files or EJB3 deployment descriptor. 无论是hbm文件还是EJB3部署描述符。

Reference: Hibernate configuration 参考:Hibernate配置

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM