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

13,146

Solution 1

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

Solution 2

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.

Solution 3

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 {
 ...
}

Solution 4

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.

Share:
13,146
Porcho
Author by

Porcho

Updated on June 04, 2022

Comments

  • Porcho
    Porcho almost 2 years

    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?

  • Porcho
    Porcho about 13 years
    it didn't work. I still get the WrongClassException after I've added @ForceDiscriminator to A. Any other idea? Thanks!