Выбор MappedSuperclass из базы данных (Hibernate)
Задача
У меня есть @MappedSuperclass вызываемые данные в качестве родителя каждой сущности в моей базе данных. Он содержит общие атрибуты, такие как Id и т. д. Затем у меня есть сущность, которая расширяет данные, которая также является @MappedSuperclass из-за общей функциональности ее подклассов. Отображение в моей базе данных правильное.
Вот пример моей иерархии
@MappedSuperclass
Data
| @MappedSuperclass
+- Employee
| | @Entity
| +- FullTimeEmployee
| | @Entity
| +- PartTimeEmployee
| @Entity
+- Store
И таблицы правильно сопоставлены:
FullTimeEmployee
PartTimeEmployee
Store
Есть ли в любом случае запрос к базе данных для всех подклассов сотрудников (FullTimeEmployee, PartTimeEmployee) как экземпляры Employee без ссылки на имя подклассов в запросе?
Что-то вроде
List<Employee> allEmployees = getAllEmployees();
Идея заключается в том, что всякий раз, когда я решаю создать другой подкласс Employee (т. е. AllDayEmployee), мне не нужно будет изменять запрос, чтобы включить имя.
Решение
Таким образом, Как правильно указал Григорий, это невозможно с
@MappedSuperclass. Поэтому я изменил его на @Entity и, поскольку я хотел, чтобы сохраните таблицу для каждого подкласса, который я использовал InheritanceType.JOINED. Таким образом, вышеприведенная иерархия теперь
@MappedSuperclass
Data
| @Entity
| @Inheritance(strategy=InheritanceType.JOINED)
+- Employee
| | @Entity
| +- FullTimeEmployee
| | @Entity
| +- PartTimeEmployee
| @Entity
+- Store
И таблицы по-прежнему:
FullTimeEmployee
PartTimeEmployee
Store
Так что теперь, чтобы получить всех сотрудников, я просто звоню:
entityManager.createQuery("from Employee").getResultList();
3 ответов:
Нет, если вы используете @MappedSuperclass
Причина этого заключается в том, что при определении базового класса как @MappedSuperclass для базового класса не создается таблица, а все свойства реплицируются в конкретные таблицы. В вашем примере будут существовать только таблицы FullTimeEmployee, PartTimeEmployee и Store.
Если вы хотите иметь возможность запрашивать сущности базового класса, вам нужно выбрать другое отображение для базовых классов. Используйте аннотацию @Inheritance на базе класс и выберите одну из 3 возможных стратегий отображения-одиночную таблицу, таблицу для каждого класса или объединенную
Да
FROM Employee WHERE Employee.<employee only properties> = someValueНо только, как сказали здесь Другие,если объект сотрудника сопоставлен. Вам даже не нужно сопоставлять его с собственной таблицей. Смотрите стратегии отображения в Hibernate.
Я, кажется, могу это сделать (хотя и использую InheritanceType.Соединено) с hibernate 5.0.8, java 1.8.0_73 и Oracle 12c-либо я неправильно понял, либо, возможно, hibernate изменился..
У меня есть следующие иерархи:
@MappedSuperclass @Inheritance(strategy=InheritanceType.JOINED) CommonRoot | | @MappedSuperclass +- Mapped | @Entity(name="Concrete1") | @Table(name="CON1") +- Concrete1 | | @Entity(name="Concrete2") | @Table(name="CON2") +- Concrete2И я могу сделать следующее HQL:
SELECT entityId FROM com.hibernatetest.Mapped ORDER BY entityId ASC, который дает эти 2 SQL-оператора:
select concrete2x0_.entityId as col_0_0_ from CON2 concrete2x0_ order by concrete2x0_.entityId ASC select concrete1x0_.entityId as col_0_0_ from CON1 concrete1x0_ order by concrete1x0_.entityId ASCИ предупреждение
WARN: HHH000180: FirstResult/maxResults specified on polymorphic query; applying in memory!Не уверен, что они означают, хотя, как это можно сделать с SQL, как:
(select entityId from CON2 union all select entityId from CON1) order by entityId ASC(и вы также можете добавить ограничьте / rownum предложения к этому, если вы хотите, хотя это становится немного неуклюжим:
select * from ( (select * from (select entityId from CON2 order by entityId ASC) where rownum <= 10) UNION ALL (select * from (select entityId from CON1 order by entityId ASC) where rownum <= 10) ) where rownum <= 10 order by entityId ASCНе уверен, почему hibernate не может этого сделать - может предложить им это.)
Comments