Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Hibernate: org.hibernate.WrongClassException, SINGLE_TABLE inheritance and DiscriminatorFormula

I'm using Hibernate 3.2.2 GA with HSQLDB 2.0 GA, and I have a class hierarchy similar to the following:

@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 {

(...)

}

I'm trying to execute the following HQL query, which returns objects from both B and C classes.

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

return query.list();

However, I get the following error:

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

The strangest thing is that the object with id 2 is a C instance...

I've googled for this error and I've found some people who's faced it, none using InheritanceType.SINGLE_TABLE and DiscrimatorFormula, though. Has anyone run into this problem?

like image 773
Porcho Avatar asked Apr 14 '11 18:04

Porcho


3 Answers

Make sure the entity is listed in your config file (persistence.xml, for example). From https://stackoverflow.com/a/14150629/116596

like image 58
Idris Mokhtarzada Avatar answered Oct 13 '22 00:10

Idris Mokhtarzada


The problem is that you're getting a list of A's and Hibernate doesn't know enough to create B's or C's in a list based on the discriminator formula. Luckily, there's an annotation to deal with this.

Some people call this a bug, and I'm sort of inclined to agree. At any rate, the abstraction seems to be a bit leaky.

Add a @ForceDiscriminator annotation to the parent entity (A) and it's likely to work properly.

This solution is Hibernate-specific. I'm not sure if the problem extends to JPA in general or if there's a JPA solution.

EDIT:

This appears not to have done the trick.

It might be worthwhile to try to get the sql that hibernate is generating for you.

Add

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

to your hibernate config and see what happens.

Getting this sql with and without the force clause might give clues as to exactly what the force does and why it's not working.

I can't think of anything else at the moment, except the NULL in your discriminator formula looks a little risky.

like image 40
Don Roby Avatar answered Oct 13 '22 00:10

Don Roby


Well, this got me curious: it may be you suffer from this issue which says:

The reason is the string is interpreted as a CHAR type rather than VARCHAR. We may change this behaviour in the future.

Can you try to apply TRIM() on the result (inside the @DiscriminatorFormula) or test with another DBMS? This doesn't seem to be Hibernate specific.

like image 20
mabi Avatar answered Oct 13 '22 00:10

mabi