开发者

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.

S开发者_如何学运维tring 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?


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


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.


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.


I solved it using the DTYPE column and WHERE clause. With your example, it would be:

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


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

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜