【问题标题】:define named query in orm.xml with jpa and hibernate使用 jpa 和 hibernate 在 orm.xml 中定义命名查询
【发布时间】:2011-01-23 07:43:10
【问题描述】:

我正在尝试将我的命名查询放入我的 orm.xml(放入 META-INF 和 persistence.xml),但我的 orm.xml 似乎被 hibernate/jpa 忽略了。

当我尝试使用 em.createNamedQuery("myQuery") 创建命名查询时,它返回找不到此查询。

我使用注解,我想在 orm.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>

这是我的 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>

我做错了什么?为什么我的 orm.xml 被忽略了?

谢谢

【问题讨论】:

  • 你的Account映射成功了吗? IE。你能像em.find(Account.class, someId)这样的查询吗?
  • 是的,我的帐户映射得很好,因为我成功地使用了注释。

标签: java hibernate orm jpa named-query


【解决方案1】:

您的 orm.xml 中有一个小错误,它破坏了整个事情。关键是元素声明的顺序应该符合各自的 XML 模式(特别是 http://java.sun.com/xml/ns/persistence/orm_1_0.xsd)。这很容易通过支持 xml 模式的验证器运行 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">
        <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>

【讨论】:

    【解决方案2】:

    “META-INF/orm.xml”是任何符合 JPA 的实体管理器都会查看的默认映射文件。

    事实上,如果你的映射文件是“META-INF/orm.xml”,你甚至不需要在你的persistence.xml中定义它。

    hibernate 配置手册是这么说的:

    类元素指定您将映射的符合 EJB3 的 XML 映射文件。该文件必须在类路径中。根据 EJB3 规范,Hibernate EntityManager 将尝试加载位于 META_INF/orm.xml 的 jar 文件中的映射文件。当然,任何显式映射文件也会被加载。事实上,您可以在映射文件元素中提供任何 XML 文件,即。 hbm 文件或 EJB3 部署描述符。

    Reference: Hibernate configuration

    【讨论】:

      【解决方案3】:

      好的,我终于明白了!

      我将我的 orm.xml 保存在 META-INF 目录中。当我将此文件移动到包含域对象的包中时(例如在我的示例中:com.mysite),不会忽略 orm.xml 并且全部运行。

      我还需要更改映射文件(persistence.xml)中的路径:com/mysite/orm.xml

      【讨论】:

      • @Jerome C. 很高兴知道 (+1)。我会试试的。
      • 因为这是解决问题的答案;)
      【解决方案4】:

      如前所述

      当我尝试使用 em.createNamedQuery("myQuery") 创建命名查询时,它返回找不到此查询

      你是对的。但是你忘记了以下内容

      如果将命名查询定义放在元素内,而不是根,它会以实体类的名称为前缀

      所以您需要将您的 namedQuery 称为

       em.createNamedQuery("Account.myQuery")
      

      我很好奇:您的 Account 类是否存储在根类路径中???如果没有,你已经修复了它丢失的包。假设 Account 类存储在 br.com.hibernate.model.domain.Account 中。所以你应该将你的实体声明为

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

      您需要将您的 namedQuery 称为

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

      只是建议:当您使用 Hibernate 作为您的 Persistence Provider 时,您不需要在 persistence.xml 文件中定义您的 Entity 类。

      问候,

      【讨论】:

      • 很好,我怀疑是这种情况,但在 xsd 中没有找到解释。你能链接那些写的文档吗?是规格吗?
      • @Bohzo 好的,Bohzo。 Java Persistence with Hibernate 一书:在 XML 元数据中定义命名查询。除此之外,JPA 规范也谈到了它。
      • 那不运行。我已经尝试了所有解决方案。对于完整的路径名,我在想包标签是为了指定在命名实体时要使用的默认包,不是吗?为简化起见,我还尝试将命名查询放在根实体映射标记中,但没有结果。就像我说的那样,orm.xml 被忽略了,因为如果我在我的 xml 中创建一个错误(没有结束标记),我在休眠启动时没有错误...
      • &lt;package&gt; 元素允许不使用完全限定名称。
      • @Pascal Thivent 感谢您的建议
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2015-11-10
      • 2021-06-13
      • 2011-01-11
      • 2021-03-07
      • 1970-01-01
      • 2011-01-23
      • 2012-02-08
      相关资源
      最近更新 更多