Выбор MappedSuperclass из базы данных (Hibernate) - PullRequest
10 голосов
/ 15 сентября 2009

Задача

У меня есть @MappedSuperclass с именем Data в качестве родителя для каждого объекта в моей базе данных. Он содержит общие атрибуты, такие как Id и т. Д. Затем у меня есть объект, расширяющий Data, который также является @MappedSuperclass из-за общей функциональности его подклассов. Отображение в моей базе данных правильное.

Вот пример моей иерархии

@MappedSuperclass
Data  
 |  @MappedSuperclass
 +- Employee  
 |      |  @Entity
 |      +- FullTimeEmployee
 |      |  @Entity
 |      +- PartTimeEmployee
 |  @Entity
 +- Store

И таблицы правильно отображаются:

FullTimeEmployee  
PartTimeEmployee  
Store

В любом случае можно ли запрашивать базу данных для всех подклассов Employee (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 ]

8 голосов
/ 15 сентября 2009

Нет, если вы используете @ MappedSuperclass

Причина этого в том, что когда вы определяете базовый класс как @MappedSuperclass, для базового класса не создается таблица, вместо этого все свойства реплицируются в конкретные таблицы. В вашем примере будут существовать только таблицы FullTimeEmployee, PartTimeEmployee и Store.

Если вы хотите иметь возможность запрашивать сущности базового класса, вам нужно выбрать другое сопоставление для базовых классов. Используйте аннотацию @Inheritance для базового класса и выберите одну из 3 возможных стратегий отображения - ОДИН СТОЛ, ТАБЛИЦА НА КЛАСС или СОЕДИНЕНИЕ

0 голосов
/ 18 марта 2016

Мне кажется, что я могу сделать это (хотя и использую InheritanceType.JOINED) с 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

(И вы также можете добавить к нему предложения limit / 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 не может это сделать - может предложить им это.)

0 голосов
/ 15 сентября 2009

Да

FROM Employee WHERE Employee.<employee only properties> = someValue

Но только, как сказали другие здесь, если сущность Employee сопоставлена. Вам не нужно даже отображать его на свой собственный стол. См. Стратегии отображения в Hibernate.

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