2010-01-26 2 views
9

У меня есть класс сущности и подкласс на основе этого объекта:JPA Native запросы для лица с наследованием

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

и

@Entity 
public class B extends A 

мне нужно выдать родной запрос, который использует хранимую процедуру только для базового класса (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 изменяется.

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

ответ

9

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

16.1.6. Обработка удела

Native запросов SQL, которые запрос для сущностей, которые отображаются как часть наследства должны включать все свойства для BaseClass и всех его подклассов.

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

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

Итак, я думал об этом, но проблема в том, что, когда Hibernate попытки раздуть объект из ResultS et row, он обнаруживает два столбца id, один из которых имеет значение null. Я полагаю, что я могу добавить дополнительный параметр where, где выбраны фильтры: b.id - null. – AnthonyF

+0

Вопрос в том, когда мы напишем его таким образом, будем ли мы всегда получать экземпляры класса B? –

0

Вы должны различать экземпляры 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

Смежные вопросы