Определить именованный запрос в orm.xml с jpa и hibernate
Я пытаюсь поместить мои именованные запросы в свой 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 игнорируется?
спасибо
Ответы
Ответ 1
Хорошо, я наконец-то понял!
Я сохранил свой orm.xml в каталоге META-INF. Когда я переношу этот файл в свой пакет, где у меня есть объект домена (например, в моем примере: com.mysite), orm.xml не игнорируется и все выполняется.
Мне также нужно изменить путь в файле-сопоставлении (persistence.xml): com/mysite/orm.xml
Ответ 2
В вашем 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>
Ответ 3
Как сказано
Когда я пытаюсь создать свой именованный запрос с помощью em.createNamedQuery( "myQuery" ), возвращает, что он не может найти этот запрос.
Вы правы. Но вы забудете следующее
Если вы поместите определение именованного запроса внутри элемента, вместо корня, , оно имеет префикс имени класса сущности
Итак, вам нужно вызвать ваш namedQuery как
em.createNamedQuery("Account.myQuery")
Мне интересно: ваш класс учетной записи хранится в корневом пути? Если нет, вы устраните недостающий пакет. Предположим, что класс 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
Просто adivice: когда вы используете Hibernate в качестве поставщика Persistence, вам не нужно определять свой класс Entity в файле persistence.xml.
С уважением,
Ответ 4
"META-INF/orm.xml" - это файл сопоставления по умолчанию, который будет рассмотрен любым администратором сущности, совместимым с JPA.
Фактически, если ваш файл сопоставления является "META-INF/orm.xml", вам не нужно даже определять его в вашем файле persistence.xml.
Вот что говорит об этом руководство по конфигурации гибернации:
Элемент class указывает файл сопоставления XML, совместимый с EJB3, который вы укажете. Файл должен находиться в пути к классам. Согласно спецификации EJB3, Hibernate EntityManager попытается загрузить файл сопоставления, расположенный в файле jar в файле META_INF/orm.xml. Конечно, будет загружен и явный файл сопоставления. На самом деле вы можете предоставить любой файл XML в элементе файла сопоставления, т.е. либо hbm файлы, либо дескриптор развертывания EJB3.
Ссылка: Конфигурация гибернации