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

    WrongClassException with inheritance

      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

        • 1. Re: WrongClassException with inheritance
          wolfc

          You must have a DiscriminatorValue defined.

          See EJB 3.0 Java Persistence API Final Release 2.1.9.1.

          • 2. Re: WrongClassException with inheritance

            Thank you very much for this hint.
            But as far as I can see, I would have to define a DiscriminatorColumn in my superclass (AbstractBalance) from which I can decide between one of my inheritances, for every id in this table

            But in my case both tables (BalanceA and BalanceB) are referencing to the same id of the superclass and it is possible that either only an object of BalanceB or instances of both objects can exist. This is dependend of an existing entry in the related tables.

            Can someone give me an idea how to solve that?

            Thanks
            Thomas