Hibernate: org.hibernate.WrongClassException, SINGLE_TABLE наследование и DiscriminatorFormula - PullRequest
5 голосов
/ 14 апреля 2011

Я использую Hibernate 3.2.2 GA с HSQLDB 2.0 GA, и у меня есть иерархия классов, подобная следующей:

@Entity
@Table(name = "A_TABLE")
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
@DiscriminatorFormula(value = "case when CODE IN (1, 2, 3, 4) then 'TypeB' 
when CODE   IN (5, 6, 7, 8) then 'TypeC' else NULL end")
@org.hibernate.annotations.Entity(dynamicUpdate = true, dynamicInsert = true)
public abstract class A{

 (...)

}


@Entity
@DiscriminatorValue("TypeB")
public class B extends A {

(...)

}


@Entity
@DiscriminatorValue("TypeC")
public class C extends A {

(...)

}

Я пытаюсь выполнить следующий HQL-запрос, который возвращает объекты из классов B и C.

String hql = "from A a where a.someAttr = 3";
Query query = session.createQuery(hql);

return query.list();

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

org.hibernate.WrongClassException: Object with id: 2 was not of the specified subclass: A (Discriminator: C      )

Самое странное, что объект с идентификатором 2 является экземпляром C ...

Я погуглил эту ошибку и нашел людей, которые сталкивались с ней, хотя никто не использовал InheritanceType.SINGLE_TABLE и DiscrimatorFormula. Кто-нибудь сталкивался с этой проблемой?

Ответы [ 4 ]

5 голосов
/ 13 августа 2013

Убедитесь, что объект указан в вашем файле конфигурации (например, persistence.xml).От https://stackoverflow.com/a/14150629/116596

1 голос
/ 21 сентября 2016

Я решил это, используя столбец DTYPE и предложение WHERE. В вашем примере это будет:

@Entity
@WHERE(clause = "DTYPE = 'B'")
public class B extends A {
 ...
}


@Entity
@WHERE(clause = "DTYPE = 'C'")
public class C extends A {
 ...
}
1 голос
/ 27 марта 2013

Что ж, меня это заинтересовало: возможно, вы страдаете от этой проблемы , в которой говорится:

Причина в том, что строка интерпретируется как тип CHAR, а не VARCHAR. Мы можем изменить это поведение в будущем.

Можете ли вы попробовать применить TRIM () к результату (внутри @DiscriminatorFormula) или выполнить тестирование с другой СУБД? Это не похоже на Hibernate.

1 голос
/ 15 апреля 2011

Проблема в том, что вы получаете список А, а Hibernate не знает достаточно, чтобы создать В или С в списке на основе формулы дискриминатора.К счастью, есть аннотация, чтобы справиться с этим.

Некоторые люди называют это ошибкой, и я склонен согласиться.В любом случае, абстракция выглядит немного утечкой.

Добавьте аннотацию @ForceDiscriminator к родительскому объекту (A), и она, вероятно, будет работать правильно.

Это решениеHibernate-специфичны.Я не уверен, распространяется ли проблема на JPA в целом или есть решение JPA.

РЕДАКТИРОВАТЬ:

Это, кажется, не сработало.

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

Добавьте

<property name="hibernate.show.sql" value="true" />

в конфигурацию hibernate и посмотрите, что произойдет.

Получение этого sql с предложением force и без него может дать подсказки относительно того, что именно делает силаи почему он не работает.

В настоящий момент я не могу думать ни о чем другом, кроме того, что NULL в вашей формуле дискриминатора выглядит немного рискованно.

...