Проблемы JPA TABLE_PER_CLASS с ManyToOne

У меня есть следующая иерархия

@MappedSuperclass
@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
public abstract class Order {
...
@Entity
@Table(name = "b_order", schema = "public")
public class BOrder extends Order implements java.io.Serializable {
...
@Entity
@Table(name = "s_order", schema = "public")
public class SOrder extends Order implements java.io.Serializable {

У меня также есть класс, в котором Tr имеет ссылки на оба конкретных подкласса

@Entity
@Table(name = "tr", schema = "public")
public class Tr implements java.io.Serializable {
...
private SOrder sOrder;
private BOrder bOrder;
...
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "s_order_id", nullable = false)
public SOrder getSOrder() {
   return this.sOrder;
}
... same for BOrder

С классами, определенными выше, ленивая загрузка работает нормально:

Tr foundTr = trDAO.findById(trId);
// test lazy loading BOrder, SOrder
BOrder foundBOrder = foundTr.getBOrder();
SOrder foundSOrder = foundTr.getSOrder();
assertNotNull(foundSOrder);
assertNotNull(foundBOrder);

Но если я попытаюсь выполнить полиморфный запрос, он не сработает:

public List<Order> getOrdersByUId(Long uId) {
    return (List<Order>) em.createQuery( //
        " select o from Order o " //
            + " order by o.created desc ") //
            .getResultList();

Я получаю сообщение об ошибке:

Заказ не отображается

На основе этого сообщения: http://java.dzone.com/articles/jpa-implementation-patterns-mapping

Кстати, при использовании прокси-серверов Hibernate имейте в виду, что ленивая загрузка класса, сопоставленного с любой из трех вышеприведенных стратегий, всегда возвращает прокси-сервер, который является экземпляром суперкласса. Цитата

что соответствует странному поведению, которое я вижу.

Однако здесь становится странно. Если я изменю родительский класс на

@Entity
// @MappedSuperclass
@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
public abstract class Order {

то есть я комментирую аннотацию MappedSuperClass, полиморфный запрос работает (создает правильный союз). Проблема в том, что когда я это делаю, LAZY загрузка из Tr в два подкласса перестает работать.

Любые идеи? Могу ли я просто использовать собственный запрос для выполнения объединения вместо JPA?

Я использую JPA 2.0 в JBoss 6.0.0 с использованием Hibernate — любая версия поставляется с JBoss.


person paul.da.programmer    schedule 28.07.2011    source источник


Ответы (1)


Нет ничего странного в том, что вы не можете запросить MappedSuperClass. Согласно спецификации JPA 2:

2.11.2 Сопоставленные суперклассы .... Сопоставленный суперкласс, в отличие от сущности, не подлежит запросу и не должен передаваться в качестве аргумента в операции EntityManager или Query. Постоянные отношения, определяемые сопоставленным суперклассом, должны быть однонаправленными. ....

Я заполнил пробелы в опубликованном вами коде (без @MappedSuperClass), и полиморфный запрос и отложенная загрузка, похоже, работают с Hibernate 3.5.6-Final. Может быть, я сделал что-то по-другому, что касается недостающих частей кода. Можете ли вы опубликовать еще более полный пример?

person Mikko Maunu    schedule 18.09.2011
comment
Я думаю, вы поняли это правильно. У меня была аналогичная проблема, и замена @ MappedSuperClass на @Entity исправила ее. Я никогда не запрашивал напрямую конкретные реализации, но запрос родителя не работал у меня... до сих пор. - person spaaarky21; 23.06.2012