-->
These old forums are deprecated now and set to read-only. We are waiting for you on our new forums!
More modern, Discourse-based and with GitHub/Google/Twitter authentication built-in.

All times are UTC - 5 hours [ DST ]



Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 12 posts ] 
Author Message
 Post subject: WrongClassException using simple table inheritance strategy
PostPosted: Sat Jan 10, 2009 8:41 am 
Newbie

Joined: Sat Jan 10, 2009 8:06 am
Posts: 6
Location: Poland
Hi,

Firstly I want to thank all hibernate developers. This framework is huge masterpiece.

During development of my app I found a strange behaviour. I tried to get rid of it changing version of hibernate but without success. I am using currently core 3.3.1 GA. I prepared simple class reproducing situation.

Code:
public class Test {
   @Entity
   @Inheritance(strategy = InheritanceType.SINGLE_TABLE)
   public static class BaseEntity {
      @Id
      @GeneratedValue
      private Long id = null;


      public Long getId() {
         return id;
      }


      public void setId(Long id) {
         this.id = id;
      }
   }

   @Entity
   public static class Device1 extends BaseEntity {}

   @Entity
   public static class Device2 extends BaseEntity {}

   @Entity
   public static class Logic1 extends BaseEntity {
      @ManyToOne
      private Device1 inputDevice = null;


      public Device1 getInputDevice() {
         return inputDevice;
      }


      public void setInputDevice(Device1 inputDevice) {
         this.inputDevice = inputDevice;
      }
   }

   @Entity
   public static class Logic2 extends BaseEntity {
      @ManyToOne(fetch = FetchType.LAZY)
      private Device2 inputDevice;


      public Device2 getInputDevice() {
         return inputDevice;
      }


      public void setInputDevice(Device2 inputDevice) {
         this.inputDevice = inputDevice;
      }
   }

   @Entity
   public static class Associacion extends BaseEntity {
      @ManyToOne
      private BaseEntity device;

      @ManyToOne
      private BaseEntity logic;


      public BaseEntity getDevice() {
         return device;
      }


      public void setDevice(BaseEntity device) {
         this.device = device;
      }


      public BaseEntity getLogic() {
         return logic;
      }


      public void setLogic(BaseEntity logic) {
         this.logic = logic;
      }

   }


   public static void main(String[] args) throws Exception {
      PropertyConfigurator.configureAndWatch("./bin/META-INF/log4j.properties");

      AnnotationConfiguration configuration = new AnnotationConfiguration();
      configuration.addAnnotatedClass(Device1.class);
      configuration.addAnnotatedClass(Device2.class);
      configuration.addAnnotatedClass(Logic1.class);
      configuration.addAnnotatedClass(Logic2.class);
      configuration.addAnnotatedClass(Associacion.class);
      configuration.configure("/META-INF/hibernate.cfg.xml");

      SessionFactory f = configuration.buildSessionFactory();
      Session session = f.openSession();

      Device2 device = new Device2();
      Logic2 logic = new Logic2();
      logic.setInputDevice(device);
      Associacion associacion = new Associacion();
      associacion.setDevice(device);
      associacion.setLogic(logic);

      Transaction tx = session.beginTransaction();
      session.save(logic);
      session.save(associacion);
      session.save(device);
      tx.commit();

      session.clear();

      associacion = (Associacion) session.get(Associacion.class, 2L);
      associacion.getDevice().getId();
      Hibernate.initialize(associacion.getLogic());
   }

}


I ends with an exception.

INFO 09/01/10 13:17:59 org.hibernate.cfg.annotations.Version (Version.java:15) - Hibernate Annotations 3.3.1.GA
INFO 09/01/10 13:17:59 org.hibernate.cfg.Environment (Environment.java:543) - Hibernate 3.3.1.GA
INFO 09/01/10 13:17:59 org.hibernate.cfg.Environment (Environment.java:576) - hibernate.properties not found
INFO 09/01/10 13:17:59 org.hibernate.cfg.Environment (Environment.java:709) - Bytecode provider name : javassist
INFO 09/01/10 13:17:59 org.hibernate.cfg.Environment (Environment.java:627) - using JDK 1.4 java.sql.Timestamp handling
INFO 09/01/10 13:17:59 org.hibernate.annotations.common.Version (Version.java:14) - Hibernate Commons Annotations 3.1.0.GA
INFO 09/01/10 13:17:59 org.hibernate.cfg.Configuration (Configuration.java:1460) - configuring from resource: /META-INF/hibernate.cfg.xml
INFO 09/01/10 13:17:59 org.hibernate.cfg.Configuration (Configuration.java:1437) - Configuration resource: /META-INF/hibernate.cfg.xml
INFO 09/01/10 13:17:59 org.hibernate.cfg.Configuration (Configuration.java:1575) - Configured SessionFactory: null
INFO 09/01/10 13:17:59 org.hibernate.cfg.AnnotationBinder (AnnotationBinder.java:418) - Binding entity from annotated class: harmony.test.Test$BaseEntity
INFO 09/01/10 13:17:59 org.hibernate.cfg.annotations.EntityBinder (EntityBinder.java:424) - Bind entity harmony.test.Test$BaseEntity on table Test$BaseEntity
INFO 09/01/10 13:17:59 org.hibernate.cfg.AnnotationBinder (AnnotationBinder.java:418) - Binding entity from annotated class: harmony.test.Test$Device1
INFO 09/01/10 13:17:59 org.hibernate.cfg.AnnotationBinder (AnnotationBinder.java:418) - Binding entity from annotated class: harmony.test.Test$Device2
INFO 09/01/10 13:17:59 org.hibernate.cfg.AnnotationBinder (AnnotationBinder.java:418) - Binding entity from annotated class: harmony.test.Test$Logic1
INFO 09/01/10 13:17:59 org.hibernate.cfg.AnnotationBinder (AnnotationBinder.java:418) - Binding entity from annotated class: harmony.test.Test$Logic2
INFO 09/01/10 13:17:59 org.hibernate.cfg.AnnotationBinder (AnnotationBinder.java:418) - Binding entity from annotated class: harmony.test.Test$Associacion
INFO 09/01/10 13:17:59 org.hibernate.cfg.AnnotationConfiguration (AnnotationConfiguration.java:365) - Hibernate Validator not found: ignoring
INFO 09/01/10 13:17:59 org.hibernate.connection.DriverManagerConnectionProvider (DriverManagerConnectionProvider.java:64) - Using Hibernate built-in connection pool (not for production use!)
INFO 09/01/10 13:17:59 org.hibernate.connection.DriverManagerConnectionProvider (DriverManagerConnectionProvider.java:65) - Hibernate connection pool size: 20
INFO 09/01/10 13:17:59 org.hibernate.connection.DriverManagerConnectionProvider (DriverManagerConnectionProvider.java:68) - autocommit mode: false
INFO 09/01/10 13:17:59 org.hibernate.connection.DriverManagerConnectionProvider (DriverManagerConnectionProvider.java:103) - using driver: oracle.jdbc.driver.OracleDriver at URL: jdbc:oracle:thin:@superhost.source.com.pl:1521:dev
INFO 09/01/10 13:17:59 org.hibernate.connection.DriverManagerConnectionProvider (DriverManagerConnectionProvider.java:109) - connection properties: {user=harmonytest, password=****}
INFO 09/01/10 13:18:01 org.hibernate.cfg.SettingsFactory (SettingsFactory.java:116) - RDBMS: Oracle, version: Oracle Database 11g Enterprise Edition Release 11.1.0.6.0 - Production
With the Partitioning option
INFO 09/01/10 13:18:01 org.hibernate.cfg.SettingsFactory (SettingsFactory.java:117) - JDBC driver: Oracle JDBC driver, version: 11.1.0.7.0-Production
INFO 09/01/10 13:18:01 org.hibernate.dialect.Dialect (Dialect.java:175) - Using dialect: org.hibernate.dialect.Oracle10gDialect
INFO 09/01/10 13:18:01 org.hibernate.transaction.TransactionFactoryFactory (TransactionFactoryFactory.java:59) - Using default transaction strategy (direct JDBC transactions)
INFO 09/01/10 13:18:01 org.hibernate.transaction.TransactionManagerLookupFactory (TransactionManagerLookupFactory.java:80) - No TransactionManagerLookup configured (in JTA environment, use of read-write or transactional second-level cache is not recommended)
INFO 09/01/10 13:18:01 org.hibernate.cfg.SettingsFactory (SettingsFactory.java:170) - Automatic flush during beforeCompletion(): disabled
INFO 09/01/10 13:18:01 org.hibernate.cfg.SettingsFactory (SettingsFactory.java:174) - Automatic session close at end of transaction: disabled
INFO 09/01/10 13:18:01 org.hibernate.cfg.SettingsFactory (SettingsFactory.java:181) - JDBC batch size: 15
INFO 09/01/10 13:18:01 org.hibernate.cfg.SettingsFactory (SettingsFactory.java:184) - JDBC batch updates for versioned data: disabled
INFO 09/01/10 13:18:01 org.hibernate.cfg.SettingsFactory (SettingsFactory.java:189) - Scrollable result sets: enabled
INFO 09/01/10 13:18:01 org.hibernate.cfg.SettingsFactory (SettingsFactory.java:197) - JDBC3 getGeneratedKeys(): disabled
INFO 09/01/10 13:18:01 org.hibernate.cfg.SettingsFactory (SettingsFactory.java:205) - Connection release mode: auto
INFO 09/01/10 13:18:01 org.hibernate.cfg.SettingsFactory (SettingsFactory.java:232) - Default batch fetch size: 1
INFO 09/01/10 13:18:01 org.hibernate.cfg.SettingsFactory (SettingsFactory.java:236) - Generate SQL with comments: disabled
INFO 09/01/10 13:18:01 org.hibernate.cfg.SettingsFactory (SettingsFactory.java:240) - Order SQL updates by primary key: disabled
INFO 09/01/10 13:18:01 org.hibernate.cfg.SettingsFactory (SettingsFactory.java:244) - Order SQL inserts for batching: disabled
INFO 09/01/10 13:18:01 org.hibernate.cfg.SettingsFactory (SettingsFactory.java:420) - Query translator: org.hibernate.hql.ast.ASTQueryTranslatorFactory
INFO 09/01/10 13:18:01 org.hibernate.hql.ast.ASTQueryTranslatorFactory (ASTQueryTranslatorFactory.java:47) - Using ASTQueryTranslatorFactory
INFO 09/01/10 13:18:01 org.hibernate.cfg.SettingsFactory (SettingsFactory.java:252) - Query language substitutions: {}
INFO 09/01/10 13:18:01 org.hibernate.cfg.SettingsFactory (SettingsFactory.java:257) - JPA-QL strict compliance: disabled
INFO 09/01/10 13:18:01 org.hibernate.cfg.SettingsFactory (SettingsFactory.java:262) - Second-level cache: enabled
INFO 09/01/10 13:18:01 org.hibernate.cfg.SettingsFactory (SettingsFactory.java:266) - Query cache: disabled
INFO 09/01/10 13:18:01 org.hibernate.cfg.SettingsFactory (SettingsFactory.java:405) - Cache region factory : org.hibernate.cache.impl.NoCachingRegionFactory
INFO 09/01/10 13:18:01 org.hibernate.cfg.SettingsFactory (SettingsFactory.java:276) - Optimize cache for minimal puts: disabled
INFO 09/01/10 13:18:01 org.hibernate.cfg.SettingsFactory (SettingsFactory.java:285) - Structured second-level cache entries: disabled
INFO 09/01/10 13:18:01 org.hibernate.cfg.SettingsFactory (SettingsFactory.java:305) - Echoing all SQL to stdout
INFO 09/01/10 13:18:01 org.hibernate.cfg.SettingsFactory (SettingsFactory.java:314) - Statistics: disabled
INFO 09/01/10 13:18:01 org.hibernate.cfg.SettingsFactory (SettingsFactory.java:318) - Deleted entity synthetic identifier rollback: disabled
INFO 09/01/10 13:18:01 org.hibernate.cfg.SettingsFactory (SettingsFactory.java:333) - Default entity-mode: pojo
INFO 09/01/10 13:18:01 org.hibernate.cfg.SettingsFactory (SettingsFactory.java:337) - Named query checking : enabled
INFO 09/01/10 13:18:02 org.hibernate.impl.SessionFactoryImpl (SessionFactoryImpl.java:187) - building session factory
INFO 09/01/10 13:18:02 org.hibernate.impl.SessionFactoryObjectFactory (SessionFactoryObjectFactory.java:105) - Not binding factory to JNDI, no JNDI name configured
INFO 09/01/10 13:18:02 org.hibernate.tool.hbm2ddl.SchemaExport (SchemaExport.java:226) - Running hbm2ddl schema export
INFO 09/01/10 13:18:02 org.hibernate.tool.hbm2ddl.SchemaExport (SchemaExport.java:251) - exporting generated schema to database
ERROR 09/01/10 13:18:05 org.hibernate.tool.hbm2ddl.SchemaExport (SchemaExport.java:348) - Unsuccessful: alter table Test$BaseEntity add constraint FK57DFF966EDA3DA97 foreign key (inputDevice_id) references Test$BaseEntity
ERROR 09/01/10 13:18:05 org.hibernate.tool.hbm2ddl.SchemaExport (SchemaExport.java:349) - ORA-02275: such a referential constraint already exists in the table

INFO 09/01/10 13:18:05 org.hibernate.tool.hbm2ddl.SchemaExport (SchemaExport.java:268) - schema export complete
Hibernate: select hibernate_sequence.nextval from dual
Hibernate: select hibernate_sequence.nextval from dual
Hibernate: select hibernate_sequence.nextval from dual
Hibernate: insert into Test$BaseEntity (inputDevice_id, DTYPE, id) values (?, 'Test$Logic2', ?)
Hibernate: insert into Test$BaseEntity (device_id, logic_id, DTYPE, id) values (?, ?, 'Test$Associacion', ?)
Hibernate: insert into Test$BaseEntity (DTYPE, id) values ('Test$Device2', ?)
Hibernate: update Test$BaseEntity set inputDevice_id=? where id=?
Hibernate: update Test$BaseEntity set device_id=?, logic_id=? where id=?
Hibernate: select test_assoc0_.id as id0_3_, test_assoc0_.device_id as device4_0_3_, test_assoc0_.logic_id as logic5_0_3_, test_basee1_.id as id0_0_, test_basee1_.inputDevice_id as inputDev3_0_0_, test_basee1_.device_id as device4_0_0_, test_basee1_.logic_id as logic5_0_0_, test_basee1_.DTYPE as DTYPE0_0_, test_devic2_.id as id0_1_, test_basee3_.id as id0_2_, test_basee3_.inputDevice_id as inputDev3_0_2_, test_basee3_.device_id as device4_0_2_, test_basee3_.logic_id as logic5_0_2_, test_basee3_.DTYPE as DTYPE0_2_ from Test$BaseEntity test_assoc0_ left outer join Test$BaseEntity test_basee1_ on test_assoc0_.device_id=test_basee1_.id left outer join Test$BaseEntity test_devic2_ on test_basee1_.inputDevice_id=test_devic2_.id left outer join Test$BaseEntity test_basee3_ on test_basee1_.logic_id=test_basee3_.id where test_assoc0_.id=? and test_assoc0_.DTYPE='Test$Associacion'
Hibernate: select test_basee0_.id as id0_3_, test_basee0_.inputDevice_id as inputDev3_0_3_, test_basee0_.device_id as device4_0_3_, test_basee0_.logic_id as logic5_0_3_, test_basee0_.DTYPE as DTYPE0_3_, test_devic1_.id as id0_0_, test_basee2_.id as id0_1_, test_basee2_.inputDevice_id as inputDev3_0_1_, test_basee2_.device_id as device4_0_1_, test_basee2_.logic_id as logic5_0_1_, test_basee2_.DTYPE as DTYPE0_1_, test_basee3_.id as id0_2_, test_basee3_.inputDevice_id as inputDev3_0_2_, test_basee3_.device_id as device4_0_2_, test_basee3_.logic_id as logic5_0_2_, test_basee3_.DTYPE as DTYPE0_2_ from Test$BaseEntity test_basee0_ left outer join Test$BaseEntity test_devic1_ on test_basee0_.inputDevice_id=test_devic1_.id left outer join Test$BaseEntity test_basee2_ on test_basee0_.device_id=test_basee2_.id left outer join Test$BaseEntity test_basee3_ on test_basee2_.logic_id=test_basee3_.id where test_basee0_.id=?
Exception in thread "main" org.hibernate.WrongClassException: Object with id: 3 was not of the specified subclass: harmony.test.Test$Device1 (loaded object was of wrong class class harmony.test.Test$Device2)
at org.hibernate.loader.Loader.instanceAlreadyLoaded(Loader.java:1267)
at org.hibernate.loader.Loader.getRow(Loader.java:1219)
at org.hibernate.loader.Loader.getRowFromResultSet(Loader.java:603)
at org.hibernate.loader.Loader.doQuery(Loader.java:724)
at org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:259)
at org.hibernate.loader.Loader.loadEntity(Loader.java:1881)
at org.hibernate.loader.entity.AbstractEntityLoader.load(AbstractEntityLoader.java:71)
at org.hibernate.loader.entity.AbstractEntityLoader.load(AbstractEntityLoader.java:65)
at org.hibernate.persister.entity.AbstractEntityPersister.load(AbstractEntityPersister.java:3072)
at org.hibernate.event.def.DefaultLoadEventListener.loadFromDatasource(DefaultLoadEventListener.java:434)
at org.hibernate.event.def.DefaultLoadEventListener.doLoad(DefaultLoadEventListener.java:415)
at org.hibernate.event.def.DefaultLoadEventListener.load(DefaultLoadEventListener.java:165)
at org.hibernate.event.def.DefaultLoadEventListener.proxyOrLoad(DefaultLoadEventListener.java:223)
at org.hibernate.event.def.DefaultLoadEventListener.onLoad(DefaultLoadEventListener.java:126)
at org.hibernate.impl.SessionImpl.fireLoad(SessionImpl.java:905)
at org.hibernate.impl.SessionImpl.internalLoad(SessionImpl.java:873)
at org.hibernate.type.EntityType.resolveIdentifier(EntityType.java:590)
at org.hibernate.type.EntityType.resolve(EntityType.java:412)
at org.hibernate.engine.TwoPhaseLoad.initializeEntity(TwoPhaseLoad.java:139)
at org.hibernate.loader.Loader.initializeEntitiesAndCollections(Loader.java:877)
at org.hibernate.loader.Loader.doQuery(Loader.java:752)
at org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:259)
at org.hibernate.loader.Loader.loadEntity(Loader.java:1881)
at org.hibernate.loader.entity.AbstractEntityLoader.load(AbstractEntityLoader.java:71)
at org.hibernate.loader.entity.AbstractEntityLoader.load(AbstractEntityLoader.java:65)
at org.hibernate.persister.entity.AbstractEntityPersister.load(AbstractEntityPersister.java:3072)
at org.hibernate.event.def.DefaultLoadEventListener.loadFromDatasource(DefaultLoadEventListener.java:434)
at org.hibernate.event.def.DefaultLoadEventListener.doLoad(DefaultLoadEventListener.java:415)
at org.hibernate.event.def.DefaultLoadEventListener.load(DefaultLoadEventListener.java:165)
at org.hibernate.event.def.DefaultLoadEventListener.proxyOrLoad(DefaultLoadEventListener.java:223)
at org.hibernate.event.def.DefaultLoadEventListener.onLoad(DefaultLoadEventListener.java:126)
at org.hibernate.impl.SessionImpl.fireLoad(SessionImpl.java:905)
at org.hibernate.impl.SessionImpl.get(SessionImpl.java:842)
at org.hibernate.impl.SessionImpl.get(SessionImpl.java:835)
at harmony.test.Test.main(Test.java:135)
INFO 09/01/10 13:18:06 org.hibernate.event.def.DefaultLoadEventListener (DefaultLoadEventListener.java:134) - Error performing load command
org.hibernate.WrongClassException: Object with id: 3 was not of the specified subclass: harmony.test.Test$Device1 (loaded object was of wrong class class harmony.test.Test$Device2)
at org.hibernate.loader.Loader.instanceAlreadyLoaded(Loader.java:1267)
at org.hibernate.loader.Loader.getRow(Loader.java:1219)
at org.hibernate.loader.Loader.getRowFromResultSet(Loader.java:603)
at org.hibernate.loader.Loader.doQuery(Loader.java:724)
at org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:259)
at org.hibernate.loader.Loader.loadEntity(Loader.java:1881)
at org.hibernate.loader.entity.AbstractEntityLoader.load(AbstractEntityLoader.java:71)
at org.hibernate.loader.entity.AbstractEntityLoader.load(AbstractEntityLoader.java:65)
at org.hibernate.persister.entity.AbstractEntityPersister.load(AbstractEntityPersister.java:3072)
at org.hibernate.event.def.DefaultLoadEventListener.loadFromDatasource(DefaultLoadEventListener.java:434)
at org.hibernate.event.def.DefaultLoadEventListener.doLoad(DefaultLoadEventListener.java:415)
at org.hibernate.event.def.DefaultLoadEventListener.load(DefaultLoadEventListener.java:165)
at org.hibernate.event.def.DefaultLoadEventListener.proxyOrLoad(DefaultLoadEventListener.java:223)
at org.hibernate.event.def.DefaultLoadEventListener.onLoad(DefaultLoadEventListener.java:126)
at org.hibernate.impl.SessionImpl.fireLoad(SessionImpl.java:905)
at org.hibernate.impl.SessionImpl.internalLoad(SessionImpl.java:873)
at org.hibernate.type.EntityType.resolveIdentifier(EntityType.java:590)
at org.hibernate.type.EntityType.resolve(EntityType.java:412)
at org.hibernate.engine.TwoPhaseLoad.initializeEntity(TwoPhaseLoad.java:139)
at org.hibernate.loader.Loader.initializeEntitiesAndCollections(Loader.java:877)
at org.hibernate.loader.Loader.doQuery(Loader.java:752)
at org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:259)
at org.hibernate.loader.Loader.loadEntity(Loader.java:1881)
at org.hibernate.loader.entity.AbstractEntityLoader.load(AbstractEntityLoader.java:71)
at org.hibernate.loader.entity.AbstractEntityLoader.load(AbstractEntityLoader.java:65)
at org.hibernate.persister.entity.AbstractEntityPersister.load(AbstractEntityPersister.java:3072)
at org.hibernate.event.def.DefaultLoadEventListener.loadFromDatasource(DefaultLoadEventListener.java:434)
at org.hibernate.event.def.DefaultLoadEventListener.doLoad(DefaultLoadEventListener.java:415)
at org.hibernate.event.def.DefaultLoadEventListener.load(DefaultLoadEventListener.java:165)
at org.hibernate.event.def.DefaultLoadEventListener.proxyOrLoad(DefaultLoadEventListener.java:223)
at org.hibernate.event.def.DefaultLoadEventListener.onLoad(DefaultLoadEventListener.java:126)
at org.hibernate.impl.SessionImpl.fireLoad(SessionImpl.java:905)
at org.hibernate.impl.SessionImpl.get(SessionImpl.java:842)
at org.hibernate.impl.SessionImpl.get(SessionImpl.java:835)
at harmony.test.Test.main(Test.java:135)
INFO 09/01/10 13:18:06 org.hibernate.event.def.DefaultLoadEventListener (DefaultLoadEventListener.java:134) - Error performing load command
org.hibernate.WrongClassException: Object with id: 3 was not of the specified subclass: harmony.test.Test$Device1 (loaded object was of wrong class class harmony.test.Test$Device2)
at org.hibernate.loader.Loader.instanceAlreadyLoaded(Loader.java:1267)
at org.hibernate.loader.Loader.getRow(Loader.java:1219)
at org.hibernate.loader.Loader.getRowFromResultSet(Loader.java:603)
at org.hibernate.loader.Loader.doQuery(Loader.java:724)
at org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:259)
at org.hibernate.loader.Loader.loadEntity(Loader.java:1881)
at org.hibernate.loader.entity.AbstractEntityLoader.load(AbstractEntityLoader.java:71)
at org.hibernate.loader.entity.AbstractEntityLoader.load(AbstractEntityLoader.java:65)
at org.hibernate.persister.entity.AbstractEntityPersister.load(AbstractEntityPersister.java:3072)
at org.hibernate.event.def.DefaultLoadEventListener.loadFromDatasource(DefaultLoadEventListener.java:434)
at org.hibernate.event.def.DefaultLoadEventListener.doLoad(DefaultLoadEventListener.java:415)
at org.hibernate.event.def.DefaultLoadEventListener.load(DefaultLoadEventListener.java:165)
at org.hibernate.event.def.DefaultLoadEventListener.proxyOrLoad(DefaultLoadEventListener.java:223)
at org.hibernate.event.def.DefaultLoadEventListener.onLoad(DefaultLoadEventListener.java:126)
at org.hibernate.impl.SessionImpl.fireLoad(SessionImpl.java:905)
at org.hibernate.impl.SessionImpl.internalLoad(SessionImpl.java:873)
at org.hibernate.type.EntityType.resolveIdentifier(EntityType.java:590)
at org.hibernate.type.EntityType.resolve(EntityType.java:412)
at org.hibernate.engine.TwoPhaseLoad.initializeEntity(TwoPhaseLoad.java:139)
at org.hibernate.loader.Loader.initializeEntitiesAndCollections(Loader.java:877)
at org.hibernate.loader.Loader.doQuery(Loader.java:752)
at org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:259)
at org.hibernate.loader.Loader.loadEntity(Loader.java:1881)
at org.hibernate.loader.entity.AbstractEntityLoader.load(AbstractEntityLoader.java:71)
at org.hibernate.loader.entity.AbstractEntityLoader.load(AbstractEntityLoader.java:65)
at org.hibernate.persister.entity.AbstractEntityPersister.load(AbstractEntityPersister.java:3072)
at org.hibernate.event.def.DefaultLoadEventListener.loadFromDatasource(DefaultLoadEventListener.java:434)
at org.hibernate.event.def.DefaultLoadEventListener.doLoad(DefaultLoadEventListener.java:415)
at org.hibernate.event.def.DefaultLoadEventListener.load(DefaultLoadEventListener.java:165)
at org.hibernate.event.def.DefaultLoadEventListener.proxyOrLoad(DefaultLoadEventListener.java:223)
at org.hibernate.event.def.DefaultLoadEventListener.onLoad(DefaultLoadEventListener.java:126)
at org.hibernate.impl.SessionImpl.fireLoad(SessionImpl.java:905)
at org.hibernate.impl.SessionImpl.get(SessionImpl.java:842)
at org.hibernate.impl.SessionImpl.get(SessionImpl.java:835)
at harmony.test.Test.main(Test.java:135)

The problem occurs only with single table inheritance strategy. Using table per class there is no exception. I use 2 ways of accessing one instance of device from associacion. Firstly direct getDevice invication, secondly indirect access by Hibernate.initialize(logic) (bellow code would also end with exception ((Logic1) getLogic()).getInputDevice().getId());


Top
 Profile  
 
 Post subject:
PostPosted: Sat Jan 10, 2009 10:59 pm 
Red Hat Associate
Red Hat Associate

Joined: Mon Aug 16, 2004 11:14 am
Posts: 253
Location: Raleigh, NC
Seems you're missing your @DiscriminatorColumn. Hibernate needs to persist what subclass you're using.

http://www.hibernate.org/hib_docs/annot ... tml#d0e870

_________________
Chris Bredesen
Senior Software Maintenance Engineer, JBoss


Top
 Profile  
 
 Post subject:
PostPosted: Sun Jan 11, 2009 10:49 am 
Newbie

Joined: Sat Jan 10, 2009 8:06 am
Posts: 6
Location: Poland
cbredesen wrote:
Seems you're missing your @DiscriminatorColumn. Hibernate needs to persist what subclass you're using.

http://www.hibernate.org/hib_docs/annot ... tml#d0e870


Thanks for your response. I think problem is more complex than this you suggested. Hibernate automagically adds discriminator column if user did not that using annotations.

I did as you said and same exception was thrown. Here is my config:
Code:
@Entity
   @Inheritance(strategy = InheritanceType.SINGLE_TABLE)
   @DiscriminatorColumn(name="type", discriminatorType=DiscriminatorType.STRING)
   @DiscriminatorValue(value="BaseEntity")
   public static class BaseEntity {
      @Id
      @GeneratedValue
      private Long id = null;


      public Long getId() {
         return id;
      }


      public void setId(Long id) {
         this.id = id;
      }
   }

   @Entity
   @DiscriminatorValue(value="Device1")
   public static class Device1 extends BaseEntity {}

   @Entity
   @DiscriminatorValue(value="Device2")
   public static class Device2 extends BaseEntity {}

   @Entity
   @DiscriminatorValue(value="Logic1")
   public static class Logic1 extends BaseEntity {
      @ManyToOne
      private Device1 inputDevice = null;


      public Device1 getInputDevice() {
         return inputDevice;
      }


      public void setInputDevice(Device1 inputDevice) {
         this.inputDevice = inputDevice;
      }
   }

   @Entity
   @DiscriminatorValue(value="Logic2")
   public static class Logic2 extends BaseEntity {
      @ManyToOne(fetch = FetchType.LAZY)
      private Device2 inputDevice;


      public Device2 getInputDevice() {
         return inputDevice;
      }


      public void setInputDevice(Device2 inputDevice) {
         this.inputDevice = inputDevice;
      }
   }

   @Entity
   @DiscriminatorValue(value="Associacion")
   public static class Associacion extends BaseEntity {
      @ManyToOne
      private BaseEntity device;

      @ManyToOne
      private BaseEntity logic;


      public BaseEntity getDevice() {
         return device;
      }


      public void setDevice(BaseEntity device) {
         this.device = device;
      }


      public BaseEntity getLogic() {
         return logic;
      }


      public void setLogic(BaseEntity logic) {
         this.logic = logic;
      }

   }


Top
 Profile  
 
 Post subject:
PostPosted: Sun Jan 11, 2009 12:33 pm 
Red Hat Associate
Red Hat Associate

Joined: Mon Aug 16, 2004 11:14 am
Posts: 253
Location: Raleigh, NC
What does the data look like? Does the persistent row contain the right discriminator value?

_________________
Chris Bredesen
Senior Software Maintenance Engineer, JBoss


Top
 Profile  
 
 Post subject:
PostPosted: Sun Jan 11, 2009 12:53 pm 
Newbie

Joined: Sat Jan 10, 2009 8:06 am
Posts: 6
Location: Poland
cbredesen wrote:
What does the data look like? Does the persistent row contain the right discriminator value?


Here it is. Seems that the data is correct.

TYPE ID INPUTDEVICE_ID DEVICE_ID LOGIC_ID
Logic2 1 3 <null> <null>
Associacion 2 <null> 3 1
Device2 3 <null> <null> <null>


Top
 Profile  
 
 Post subject:
PostPosted: Mon Jan 12, 2009 8:58 pm 
Newbie

Joined: Sat Jan 10, 2009 8:06 am
Posts: 6
Location: Poland
mk195787 wrote:
cbredesen wrote:
What does the data look like? Does the persistent row contain the right discriminator value?


Here it is. Seems that the data is correct.

TYPE ID INPUTDEVICE_ID DEVICE_ID LOGIC_ID
Logic2 1 3 <null> <null>
Associacion 2 <null> 3 1
Device2 3 <null> <null> <null>


Anyone?


Top
 Profile  
 
 Post subject:
PostPosted: Tue Jan 13, 2009 5:37 am 
Beginner
Beginner

Joined: Wed Nov 19, 2008 8:25 am
Posts: 46
Location: Saint Petersburg, Russian Federation
Hibernate goes crazy because you have two distinct properties at the java level (Logic1.inputDevice and Logic2.inputDevice)) that are mapped to the same database column. Hence, solution is to resolve that. There are at least two ways to go:

    Explicitly define distinct columns:
    Code:
        @Entity
        public static class Logic1 extends BaseEntity {
            @ManyToOne
            [b]@JoinColumn(name = "input1")[/b]
            private Device1 inputDevice = null;
            ...
        }

        @Entity
        public static class Logic2 extends BaseEntity {
            @ManyToOne(fetch = FetchType.LAZY)
            [b]@JoinColumn(name = "input2")[/b]
            private Device2 inputDevice;
             ...
        }

    Rename the property(ies), i.e. perform the same action as above but implicitly:
    Code:
        @Entity
        public static class Logic1 extends BaseEntity {
            @ManyToOne
            private Device1 inputDevice1 = null;


            public Device1 getInputDevice() {
                return inputDevice1;
            }

            public void setInputDevice(Device1 inputDevice) {
                this.inputDevice1 = inputDevice;
            }
        }

        @Entity
        public static class Logic2 extends BaseEntity {
            @ManyToOne(fetch = FetchType.LAZY)
            private Device2 inputDevice2;


            public Device2 getInputDevice() {
                return inputDevice2;
            }

            public void setInputDevice(Device2 inputDevice) {
                this.inputDevice2 = inputDevice;
            }
        }



Also note that your mapping is extremely inefficient - just check the generated sql.


Top
 Profile  
 
 Post subject:
PostPosted: Tue Jan 13, 2009 10:53 am 
Red Hat Associate
Red Hat Associate

Joined: Mon Aug 16, 2004 11:14 am
Posts: 253
Location: Raleigh, NC
You nailed it I believe. I should have noticed that but didn't spend too much time looking at it. Hibernate should probably disallow this or warn against it (anyone wanna file a JIRA?).

denis.zhdanov++

_________________
Chris Bredesen
Senior Software Maintenance Engineer, JBoss


Top
 Profile  
 
 Post subject:
PostPosted: Tue Jan 13, 2009 11:20 am 
Newbie

Joined: Sat Jan 10, 2009 8:06 am
Posts: 6
Location: Poland
Thanks.
I hoped this can be solved without extra configuration. Hibernate has enough info to distinguish Device classes despite they are mapped to the same collumn. That doesn't solve my problem, but you are right. Maybe I wanted too much.

Regarding efficiency this is only replication of my issue. My target was to present my problem writing as least code as I can. Yes, you are right this code is extremely inefficient :).

Sog from me:)

Regards

denis.zhdanov wrote:
Hibernate goes crazy because you have two distinct properties at the java level (Logic1.inputDevice and Logic2.inputDevice)) that are mapped to the same database column. Hence, solution is to resolve that. There are at least two ways to go:

    Explicitly define distinct columns:
    Code:
        @Entity
        public static class Logic1 extends BaseEntity {
            @ManyToOne
            [b]@JoinColumn(name = "input1")[/b]
            private Device1 inputDevice = null;
            ...
        }

        @Entity
        public static class Logic2 extends BaseEntity {
            @ManyToOne(fetch = FetchType.LAZY)
            [b]@JoinColumn(name = "input2")[/b]
            private Device2 inputDevice;
             ...
        }

    Rename the property(ies), i.e. perform the same action as above but implicitly:
    Code:
        @Entity
        public static class Logic1 extends BaseEntity {
            @ManyToOne
            private Device1 inputDevice1 = null;


            public Device1 getInputDevice() {
                return inputDevice1;
            }

            public void setInputDevice(Device1 inputDevice) {
                this.inputDevice1 = inputDevice;
            }
        }

        @Entity
        public static class Logic2 extends BaseEntity {
            @ManyToOne(fetch = FetchType.LAZY)
            private Device2 inputDevice2;


            public Device2 getInputDevice() {
                return inputDevice2;
            }

            public void setInputDevice(Device2 inputDevice) {
                this.inputDevice2 = inputDevice;
            }
        }


Also note that your mapping is extremely inefficient - just check the generated sql.


Top
 Profile  
 
 Post subject:
PostPosted: Tue Jan 20, 2009 3:19 am 
Beginner
Beginner

Joined: Wed Nov 19, 2008 8:25 am
Posts: 46
Location: Saint Petersburg, Russian Federation
It's quite interesting but the example works fine if we use xml-based approach. I.e. the properties are correctly resolved involving discriminator column to the processing.

I don't have an answer for such behavior.


Top
 Profile  
 
 Post subject:
PostPosted: Tue Jan 20, 2009 6:10 am 
Newbie

Joined: Sat Jan 10, 2009 8:06 am
Posts: 6
Location: Poland
denis.zhdanov wrote:
It's quite interesting but the example works fine if we use xml-based approach. I.e. the properties are correctly resolved involving discriminator column to the processing.

I don't have an answer for such behavior.


Wow. Maybe this should be sent to JIRA?


Top
 Profile  
 
 Post subject:
PostPosted: Tue Jan 20, 2009 6:23 am 
Beginner
Beginner

Joined: Wed Nov 19, 2008 8:25 am
Posts: 46
Location: Saint Petersburg, Russian Federation
It's worth to do that imho.


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 12 posts ] 

All times are UTC - 5 hours [ DST ]


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum

Search for:
© Copyright 2014, Red Hat Inc. All rights reserved. JBoss and Hibernate are registered trademarks and servicemarks of Red Hat, Inc.