Аннотация Hibernate Polymorphism.EXPLICIT не работает?

Я знаю, что есть несколько сообщений об этом, но им около года, а ответа нет. На самом деле мы используем Hibernate 4.2.1.Final вместо PostgreSQL 8.4. У нас есть два таких объекта

Объект A (высший класс иерархии)

@Entity
@Inheritance(strategy = InheritanceType.JOINED)
@Polymorphism(type = PolymorphismType.EXPLICIT)
public class A {
    @Id
    @GeneratedValue
    private Long id;

    public A() {

    }

    public A(Long id) {
        super();
        this.id = id;
    }

    // Setters, getteres, hashCode and equals
}

Объект B (подкласс)

@Entity
public class B extends A{
    String value;

    public B(){

    }

    public B(String value) {
        super();
        this.value = value;
    }

    public B(Long id, String value) {
        super(id);
        this.value = value;
    }

    // Setters, getteres, hashCode and equals
}

Как видите, сущность аннотируется PolymorphismType.EXPLICIT, но при получении верхнего класса с помощью

ArrayList<A> lista = (ArrayList<A>) session.createCriteria(A.class).list();

мы также получаем подклассы B со свойством String value. На самом деле оператор SQL содержит left outer join B. Это все-таки баг четвертой версии Hibernate или я что-то не так делаю?

С наилучшими пожеланиями


person hespresati    schedule 24.06.2013    source источник


Ответы (1)


На мой взгляд, соответствующая документация и сама функция очень запутаны. Из главы 5:

Явный полиморфизм означает, что экземпляры класса будут возвращены только запросами, которые явно называют этот класс.

что укажет мне, что ваш запрос должен работать. Но то, что вы пытаетесь сделать, похоже, не является их намерением, как вы можете видеть позже в том же абзаце:

Явный полиморфизм полезен, когда два разных класса сопоставляются с одной и той же таблицей. Это позволяет использовать «облегченный» класс, содержащий подмножество столбцов таблицы.

Здесь они говорят о том, что B и A сопоставляются с одной и той же таблицей, но не имеют фактического отношения классов. Вы можете увидеть повторение этого мнения в старой JIRA. билет. Я предполагаю, что это означает, что если они не имеют отношений классов, но находятся в одной таблице, то вы можете использовать полиморфизм IMPLICIT, чтобы получить оба с одним и тем же запросом, но это кажется совершенно странным, учитывая, что они не разделяют подкласс Java .

Итак, резюме таково, что PolymorphismType.EXPLICIT не делает того, что вы думаете. На мой взгляд, он должен делать то, что вы ожидаете, исходя из первой приведенной выше цитаты.

person sharakan    schedule 24.06.2013
comment
Да, документация очень запутанная и требует пояснений. Итак, теперь вопрос заключается в том, что мы используем таблицу для подкласса вместо того, чтобы иметь A и B в одной таблице (поскольку реальная схема не так проста), есть способ получить только A сущности без извлечения всех данных и составления ответа, создающего экземпляры A вручную? Я имею в виду, оператор SELECT SQL без left outer join B. Спасибо - person hespresati; 25.06.2013
comment
Можете ли вы разорвать связь наследования между A и B? - person sharakan; 25.06.2013
comment
Я думаю, мы не можем. Настоящая унаследованная схема представляет собой дерево, такое как Conact, Company, расширяющая контакт, и Person, расширяющая контакт. И есть другие сущности, которые простираются от компании, другие сущности, которые простираются от человека и так далее. - person hespresati; 25.06.2013
comment
Способ, которым я справлялся с подобными ситуациями в прошлом, заключается в том, чтобы сделать общий подкласс более высокого уровня @MappedSuperclass, и мои запросы относятся к подклассам. Итак, с точки зрения базы данных, между, скажем, Компанией и Человеком нет реальной связи. Итак, возможно, вы хотите преобразовать Contact в @MappedSuperclass и запрашивать только Person и Company? - person sharakan; 25.06.2013
comment
Это был один из подходов, о которых я думал, но у нас будет та же проблема при запросе к компании или человеку. Запущенные операторы SQL будут иметь соединения с подклассами - person hespresati; 25.06.2013
comment
Это один из недостатков таблицы на подкласс. Если вы хотите избежать этого, возможно, вы захотите перейти к иерархии таблиц для классов. - person sharakan; 25.06.2013
comment
Соединения в подклассах в порядке при их извлечении. Проблема заключается в запросе высшего класса. Даже с @MappedSuperclass проблема сохранится. Мы решили пройти через table-per-subclass с целью явного полиморфизма, просто запрашивая единственную таблицу. Спасибо за вашу помощь. Я буду продолжать работать над этим. С наилучшими пожеланиями - person hespresati; 27.06.2013
comment
@hespresati возможно (не уверен в этом), что если вы поместите EXPLICIT в подклассы, ваши запросы будут работать так, как вы хотите. Другой способ сделать это (который может быть лучше) - перейти от наследования к композиции: смоделируйте класс верхнего уровня как контейнер подклассов, лениво загрузите ассоциацию сущностей. - person sharakan; 27.06.2013
comment
Есть ли недостатки при использовании PolymorphismType.EXPLICIT? - person svlada; 19.04.2015