Собственный запрос JPA для сущности с наследованием - PullRequest
10 голосов
/ 26 января 2010

У меня есть класс сущности и подкласс, основанный на этой сущности:

@Entity
@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
public class A

и

@Entity
public class B extends A

Мне нужно выполнить собственный запрос, который использует хранимую процедуру на базетолько класс (А).Если я попытаюсь сделать это следующим образом:

entityManager.createNativeQuery("select * from A a where procedure(f)",A.class).getResultList()

Я получу сообщение об ошибке "Столбец clazz_ не найден в ResultSet".Я предполагаю, что поставщик JPA добавляет этот столбец, чтобы различать базовый класс и расширенный класс.Я могу обойти эту проблему, явно добавив столбец clazz и все поля из подкласса:

entityManager.createNativeQuery("select *,1 as clazz_,null as prop1,null as prop2 from A a where procedure(f)",A.class).getResultList()

, где «prop1» и «prop2» - это свойства подкласса B. Однако это выглядит какненужный взлом и склонен к проблемам обслуживания, если подкласс B изменяется.

У меня такой вопрос: как я могу выполнить запрос с использованием хранимой процедуры для объекта, для которого определено наследование?

Ответы [ 2 ]

9 голосов
/ 27 января 2010

Как вы, наверное, видели, команда Hibernate не потратила много времени на то, чтобы определить, как вы это делаете ... в документации просто говорится:

16.1.6. Обработка наследства

Собственные запросы SQL, которые запрашивают объекты, которые отображаются как часть наследование должно включать все свойства для базового класса и все его подклассы.

Так что, если вы хотите использовать собственные запросы, похоже, что вы застряли, делая что-то подобное. Что касается озабоченности по поводу изменения подкласса B, возможно, чуть менее обременительным способом реализации этого будет попытка использовать синтаксис LEFT OUTER JOIN для свойства общего идентификатора:

entityManager.createNativeQuery("select a.*, b*, 1 as clazz_, from A a LEFT OUTER JOIN B b on id = a.id where procedure(f)",A.class).getResultList()

Таким образом, вы всегда получите все свойства от B, если добавите или удалите некоторые из них.

0 голосов
/ 23 сентября 2015

Вам нужно отличать экземпляры A от экземпляров B, используя дискриминатор. Используйте одну из следующих аннотаций:

@DiscriminatorValue

http://docs.oracle.com/javaee/5/api/javax/persistence/DiscriminatorValue.html

@DiscriminatorColumn

https://docs.oracle.com/javaee/5/api/javax/persistence/DiscriminatorColumn.html

@DiscriminatorFormula

http://docs.jboss.org/hibernate/annotations/3.5/reference/en/html/entity.html#d0e1168

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...