Наследование со стратегией SINGLE_TABLE в JPA и @Discriminator в геттере

Проблема с наследованием в сущностях JPA со стратегией SINGLE_TABLE. В геттерах @Discriminator уменьшает диапазон наследования.

У меня есть следующая структура:

@Entity
@Inheritance(strategy=InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn(name="type")
@DiscriminatorValue("A")
class A {
...
}

@Entity
@DiscriminatorValue("B")
class B extends A {
...
}

@Entity
@DiscriminatorValue("C")
class C extends B {
...
}

@Entity
class Something{
@ManyToMany // blah blah
private List<B> listB; // getters and setters
}

Проблема следующая. У меня есть объект класса C (при условии, что наследование C также является B). Когда я делаю:

Something s = Something.findById(11); // Here is listB with elements of type C and B
List<B> listB = s.getListB();

Я извлекаю только объекты класса B, а не C. Но C расширяет B, поэтому он также должен быть в списке. Геттер строит такой запрос:

SELECT t1.id, t1.type, t1.sys_modified_date, t1.sys_created_date, t1.name,  t1.shortName
FROM something_b t0 INNER JOIN A t1 ON t0.listB = t1.id 
WHERE t0.news = ? AND t1.type = ? 
[params=(long) 205, (String) B]

Проблема в том, что этот геттер (Something.getListB) сводит этот список только к классу B (по дискриминатору B). Это приводит к тому, что объект класса C отсутствует в списке. Это вызвано @Discriminator указанием строгого типа "t1.type = B". Не позволяет разместить там набор/список типа "t1.type IN (B,C)".

Пользовательские запросы JPQL представляют собой конструкции по-разному:

SELECT t1.id, t1.type, t1.sys_modified_date, t1.sys_created_date, t1.name,  t1.shortName
FROM something_b t0 INNER JOIN A t1 ON t0.listB = t1.id 
WHERE t0.news = ? AND t1.type IN (?, ?) 
[params=(long) 205, (String) B, (String) C]

и работают как надо. А как же геттер?

Интересен тот факт, что когда я меняю класс Something с класса B на класс A (базовый для всех): @Entity class Something{ @ManyToMany // бла-бла частный список listA; // геттеры и сеттеры }

это решает проблему. В геттере в запросе:

SELECT t1.id, t1.type, t1.sys_modified_date, t1.sys_created_date, t1.name,  t1.shortName
FROM something_b t0 INNER JOIN A t1 ON t0.listB = t1.id 
WHERE t0.news = ? 
[params=(long) 205]

исчезает "И t1.type =?". Это работает, но мешает сопоставлению «объектов реального мира» с «сущностями ORM». Это решение меняется, ухудшает эту абстракцию. Это не элегантное решение.

Вопрос:

Как я могу решить эту проблему?

Могу ли я использовать собственный запрос JPQL в геттере?

Как заставить этот геттер извлекать объекты B и C?

У вас есть другое предложение вместо того, чтобы изменить список на список???


person Mariomario85    schedule 02.02.2012    source источник


Ответы (1)


Какой провайдер JPA вы используете? Похоже на ошибку. Это должно работать с EclipseLink.

person James    schedule 02.02.2012
comment
Мы используем Open JPA версии 2.1.0. Есть ли у вас опыт работы с другими провайдерами JPA с точки зрения ошибок? - person Mariomario85; 03.02.2012