Наследование со стратегией SINGLE_TABLE в JPA и @Discriminator в геттере - PullRequest
0 голосов
/ 02 февраля 2012

Проблема с наследованием в объектах 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, поэтому он также должен быть в списке.Getter создает такой запрос:

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]

Проблема в том, что этот getter (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]

иони работают как надо.Но что насчет getter?

Интересно то, что когда я меняю класс Something с класса B на класс A (базовый для всех): @Entity class Something {@ManyToMany // бла-бла-приват Private List 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]

исчезает "AND t1.type =?".Это работает, но мешает отображению из "объектов реального мира" в "объекты ORM".Это решение меняется, усугубляет эту абстракцию.Это не элегантное решение.

Вопрос:

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

Можно ли использовать пользовательский запрос JPQL в геттере?

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

Есть ли у вас другое предложение вместо изменения List на List ???

1 Ответ

0 голосов
/ 02 февраля 2012

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

...