2 Replies Latest reply on Jan 15, 2007 6:19 AM by Thomas Hamacher

    WrongClassException with inheritance

    Thomas Hamacher Novice

      Hi,

      I have a problem with an inheritance-model and I´m not sure, if I´m trying to do something, that´s not possible this way. From the object-oriented point of view and the database-oriented point of view this should be possible, but it seems, as if ejb3 needs some more information.

      The object inheritance looks like this:

       AbstractBalance
       A
       |
       |
       +---------------------+-------------------------+
       | |
       BalanceA BalanceB
      


      an it should be realized through a InheritanceType.JOINED with the following database-tables all referencing to the same id:


      CREATE TABLE balance
      (
       id INTEGER NOT NULL,
       code_currency VARCHAR(3) NOT NULL
      );
      
      CREATE TABLE balance_a
      (
       id INTEGER NOT NULL,
       credit NUMERIC(10, 2) NOT NULL
      );
      
      ALTER TABLE balance_a ADD CONSTRAINT pk_balance_a
       PRIMARY KEY (id);
      
      ALTER TABLE balance_a ADD CONSTRAINT fk__balance_a
       FOREIGN KEY (id) REFERENCES balance (id) ON DELETE NO ACTION;
      
      CREATE TABLE balance_b
      (
       id INTEGER NOT NULL,
       income NUMERIC(10, 2) NOT NULL
      );
      
      ALTER TABLE balance_b ADD CONSTRAINT fk__balance_b
       FOREIGN KEY (id) REFERENCES balance (id) ON DELETE NO ACTION;
      


      and these annotations:

      @Entity
      @Table(name = "balance")
      @Inheritance(strategy=InheritanceType.JOINED)
      public abstract class Balance implements Serializable {
      
       @Id
       @Column(name = "id", nullable = false)
       private Integer id;
      
      ....
      
      @Entity
      @Table(name = "balance_a")
      public class BalanceA extends Balance implements Serializable {
      
      ....
      
      @Entity
      @Table(name = "balance_b")
      public class BalanceB extends Balance implements Serializable {
      
      ....
      


      The reason for that is, that I want to define values in the balance-table, that are necessary and identical for both of the subclasses. Unfortunately I get a WrongClassException when I try to load these classes from a referenced class and have the same id´s in every table. If I remove the referencing id in balance_b, everything works fine, although BalanceB is not reference.

      10:03:30,617 INFO [DefaultLoadEventListener] Error performing load command
      org.hibernate.WrongClassException: Object with id: 2 was not of the specified subclass: entity.BalanceB (loaded object was of wrong class class entity.BalanceA)
       at org.hibernate.loader.Loader.instanceAlreadyLoaded(Loader.java:1234)
       at org.hibernate.loader.Loader.getRow(Loader.java:1186)
       at org.hibernate.loader.Loader.getRowFromResultSet(Loader.java:568)
       at org.hibernate.loader.Loader.doQuery(Loader.java:689)
       at org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:224)
       at org.hibernate.loader.Loader.loadEntity(Loader.java:1784)
       at org.hibernate.loader.entity.AbstractEntityLoader.load(AbstractEntityLoader.java:48)
       at org.hibernate.loader.entity.AbstractEntityLoader.load(AbstractEntityLoader.java:42)
       at org.hibernate.persister.entity.AbstractEntityPersister.load(AbstractEntityPersister.java:2977)
       at org.hibernate.event.def.DefaultLoadEventListener.loadFromDatasource(DefaultLoadEventListener.java:393)
       at org.hibernate.event.def.DefaultLoadEventListener.doLoad(DefaultLoadEventListener.java:374)
       at org.hibernate.event.def.DefaultLoadEventListener.load(DefaultLoadEventListener.java:137)
       at org.hibernate.event.def.DefaultLoadEventListener.proxyOrLoad(DefaultLoadEventListener.java:193)
       at org.hibernate.event.def.DefaultLoadEventListener.onLoad(DefaultLoadEventListener.java:101)
       at org.hibernate.impl.SessionImpl.fireLoad(SessionImpl.java:878)
       at org.hibernate.impl.SessionImpl.internalLoad(SessionImpl.java:846)
       at org.hibernate.type.EntityType.resolveIdentifier(EntityType.java:266)
       at org.hibernate.type.EntityType.resolve(EntityType.java:303)
       at org.hibernate.engine.TwoPhaseLoad.initializeEntity(TwoPhaseLoad.java:116)
       at org.hibernate.loader.Loader.initializeEntitiesAndCollections(Loader.java:842)
      


      Did I miss anything in the annotation or is it not possible to do it that way?

      Thank you very much for your help

      Thomas