Object with id was not of the specified subclass

25,439

Solution 1

Can you tell what data records you have in DB?

It seems the id's between different tables has same value, so when hibernate is trying to load an entity with a specific id and if another entity with same id is already present in memory then hibernate is complaining about this issue.

Solution 2

I ran into the same exception, but for a completely different reason.

We have entities A, B and C. B and C extend A, A is abstract and we used SINGLE_TABLE inheritance.

We also have entities X, Y and Z with the same properties (Y and Z extend X, X is abstract and we used SINGLE_TABLE inheritance).

X has a field of A and is of generic Type A:

public abstract class X<T extends A> {
    @ManyToOne
    T field;
}

Y and Z specify the types of B and C respectively:

@Inheritance(strategy=InheritanceType.SINGLE_TABLE)
@DiscriminatorValue(value = "Y")
public abstract class Y extends X<B> {
}

We had other classes implement X without specifying a concrete type (keeping < T extends A >) - even when there are no Y or Z in the database (which means Hibernate never has to load any and should actually never create objects Y or Z) we would (sometimes) get a org.hibernate.WrongClassException. Our solution was to remove the concrete types B and C from classes Y and Z and use casts in our code.

Additional note: this seemed to work fine for some years, but popped up after an architectural change where neither hibernate configuration nor any of the classes were changed (we just renamed some packages) and then didn't go away until we removed the concrete generic types.

Share:
25,439
Alberson Melo
Author by

Alberson Melo

Updated on April 17, 2020

Comments

  • Alberson Melo
    Alberson Melo about 4 years

    I'm getting a weird error on my application.
    I'm trying to retrieve an list of entity from database (MySQL) with session.createCriteria().list() but I'm getting this org.hibernate.WrongClassException.

    I have looked up this error and I know what it means, but I don't know how to solve it on my context.

    I have the following database structure:

    CREATE TABLE vtiger_crmentity (
    `crmid` int(19) NOT NULL
    )
    
    CREATE TABLE vtiger_account (
        `accountid` int(19) NOT NULL DEFAULT 0
    )
    
    CREATE TABLE vtiger_accountscf (
        `accountid` int(19) NOT NULL DEFAULT 0
    )
    
    CREATE TABLE vtiger_accoutshipads (
    `accountaddressid` int(19) NOT NULL DEFAULT 0
    )
    
    CREATE TABLE vtiger_accountbillads (
        `accountaddressid` int(19) NOT NULL DEFAULT 0
    )
    

    So, quickly explaining, all the tables are linked by the these id columns, and in the last level, the vtiger_accountscf table has 1 vtiger_accountshipads and 1 vtiger_accountbillads. All the tables have the same PK.
    So I made my classes like this (stubs):

    @Entity
    @Inheritance(strategy = InheritanceType.JOINED)
    @Table(name = "vtiger_crmentity")
    public class VtigerCrmentity {
      @Id
      @Basic(optional = false)
      @Column(name = "crmid", nullable = false)
      public Integer getId() {
        return this.id;
    
      }
    }
    
    
    @Entity
    @PrimaryKeyJoinColumn(name = "accountid")
    @Inheritance(strategy = InheritanceType.JOINED)
    @Table(name = "vtiger_account")
    public class VtigerAccount extends VtigerCrmentity {
    
    }
    
    @Entity
    @PrimaryKeyJoinColumn(name = "accountid")
    @Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
    @Table(name = "vtiger_accountscf")
    public class VtigerAccountscf extends VtigerAccount {
    }
    
    @Entity
    @PrimaryKeyJoinColumn(name = "accountaddressid")
    @Table(name = "vtiger_accountbillads")
    public class VtigerAccountbillads extends VtigerAccountscf {
    }
    
    @Entity
    @PrimaryKeyJoinColumn(name = "accountaddressid")
    @Table(name = "vtiger_accountshipads")
    public class VtigerAccountshipads extends VtigerAccountscf {
    }
    

    And here's my problem. When I do:

    getSession().createCriteria(VtigerAccountbillads.class).list();
    

    I'm getting the exception:

    org.hibernate.WrongClassException: Object with id: 11952 was not of the specified subclass: VtigerAccountbillads (loaded object was of wrong class class VtigerAccountshipads)
        at org.hibernate.loader.Loader.instanceAlreadyLoaded(Loader.java:1391)
        at org.hibernate.loader.Loader.getRow(Loader.java:1344)
        at org.hibernate.loader.Loader.getRowFromResultSet(Loader.java:611)
        at org.hibernate.loader.Loader.doQuery(Loader.java:829)
        at org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:274)
        at org.hibernate.loader.Loader.doList(Loader.java:2533)
        at org.hibernate.loader.Loader.listIgnoreQueryCache(Loader.java:2276)
        at org.hibernate.loader.Loader.list(Loader.java:2271)
        at org.hibernate.loader.criteria.CriteriaLoader.list(CriteriaLoader.java:119)
        at org.hibernate.impl.SessionImpl.list(SessionImpl.java:1716)
        at org.hibernate.impl.CriteriaImpl.list(CriteriaImpl.java:347)
    

    By project limitations, I'm not using spring or nothing similar to configure the Hibernate and create the session.

    Is my mapping wrong?