-->
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.  [ 8 posts ] 
Author Message
 Post subject: Problem with inheritance and recursive relationship
PostPosted: Mon Dec 01, 2003 10:39 am 
Newbie

Joined: Mon Dec 01, 2003 10:23 am
Posts: 7
Hi,
I'm new hibernate and have run into a problem where I keep getting WrongClassException for no apparent reason. If someone could help out it would be greatly appreciated. I get the following exception when I try to do the following:

Code:
Item item = (Item)session.load(model.Item.class, new Integer(id));


Here is the exception message:

net.sf.hibernate.WrongClassException: Object with id: 1984 was not of the specified subclass: model.Pack (loaded object was of wrong class)

Here is my mapping:

Code:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD//EN" "http://hibernate.sourceforge.net/hibernate-mapping-2.0.dtd">
<hibernate-mapping>
   <class name="model.Item" table="Item" discriminator-value="Item">
      <id name="id" type="int" unsaved-value="0">
         <column name="id" not-null="true"/>
         <generator class="identity"/>
      </id>
      <discriminator column="type" type="string" length="10"/>
      <property name="name" type="string" length="100"/>
      <property name="description" type="string" length="1000"/>
      <property name="keywords" type="string" length="50"/>
      <set name="creators" table="ItemCreator" lazy="true">
         <key column="itemId"/>
         <many-to-many column="creatorId" class="model.Creator"/>
      </set>
      <subclass name="model.Volume" discriminator-value="Volume">
         <property name="code" type="string" length="8"/>
         <property name="image" type="string" length="50"/>
         <property name="thumbnail" type="string" length="50"/>
         <many-to-one name="label" column="labelId" class="model.Label"/>
         <set name="packs" table="Item" inverse="true" order-by="name asc" where="type='Pack'" lazy="true">
            <key column="parentItemId"/>
            <one-to-many class="model.Pack"/>
         </set>
      </subclass>
      <subclass name="model.Pack" discriminator-value="Pack">
         <property name="code" type="string" length="8"/>
         <property name="image" type="string" length="50"/>
         <property name="thumbnail" type="string" length="50"/>
         <property name="editor" type="string" length="50"/>
         <property name="visible" type="boolean"/>
         <many-to-one name="volume" column="parentItemId" class="model.Volume"/>
         <set name="files" table="Item" inverse="true" order-by="name asc" where="type='File'" lazy="true">
            <key column="parentItemId"/>
            <one-to-many class="model.File"/>
         </set>
      </subclass>
      <subclass name="model.File" discriminator-value="File">
         <property name="itemFile" type="string" length="50"/>
         <property name="itemFileType" type="string" length="10"/>
         <property name="itemFileSize" type="int" length="10"/>
         <many-to-one name="pack" column="parentItemId" class="model.Pack"/>
      </subclass>
   </class>
</hibernate-mapping>



Worth noting is that the row with id 1984 has type = 'Pack' which is the discriminator that points to model.Pack

Does anyone have a clue?

Thanks in advance,
Jonas Klemming


Top
 Profile  
 
 Post subject:
PostPosted: Mon Dec 01, 2003 11:18 am 
Hibernate Team
Hibernate Team

Joined: Sun Sep 14, 2003 3:54 am
Posts: 7256
Location: Paris, France
The class type loaded model.Pack must be assignable from the parameter class type. This is not the case.

try session.iterate(from Item item where item.id = :id, ...)

_________________
Emmanuel


Top
 Profile  
 
 Post subject:
PostPosted: Mon Dec 01, 2003 11:35 am 
Newbie

Joined: Mon Dec 01, 2003 10:23 am
Posts: 7
Thanks for the quick reply!

I tried the session.iterate approach (even though I didn't understand your explaination) and got the same error.

Exception with trace:

Code:
net.sf.hibernate.WrongClassException: Object with id: 1984 was not of the specified subclass: com.primesounds.model.Pack (loaded object was of wrong class) at net.sf.hibernate.loader.Loader.instanceAlreadyLoaded(Loader.java:300) at net.sf.hibernate.loader.Loader.getRow(Loader.java:278) at net.sf.hibernate.loader.Loader.doFind(Loader.java:159) at net.sf.hibernate.loader.Loader.loadEntity(Loader.java:587) at net.sf.hibernate.loader.EntityLoader.load(EntityLoader.java:42) at net.sf.hibernate.persister.EntityPersister.load(EntityPersister.java:396) at net.sf.hibernate.impl.SessionImpl.doLoad(SessionImpl.java:1889) at net.sf.hibernate.impl.SessionImpl.doLoadByClass(SessionImpl.java:1757) at net.sf.hibernate.impl.SessionImpl.internalLoad(SessionImpl.java:1716) at net.sf.hibernate.type.ManyToOneType.resolveIdentifier(ManyToOneType.java:62) at net.sf.hibernate.type.EntityType.nullSafeGet(EntityType.java:109) at net.sf.hibernate.impl.IteratorImpl.postNext(IteratorImpl.java:57) at net.sf.hibernate.impl.IteratorImpl.<init>(IteratorImpl.java:43) at net.sf.hibernate.hql.QueryTranslator.iterate(QueryTranslator.java:806) at net.sf.hibernate.impl.SessionImpl.iterate(SessionImpl.java:1409) at net.sf.hibernate.impl.SessionImpl.iterate(SessionImpl.java:1386)


What exactly do you mean by:
Quote:
The class type loaded model.Pack must be assignable from the parameter class type. This is not the case.



Regards,
Jonas[/code]


Top
 Profile  
 
 Post subject:
PostPosted: Mon Dec 01, 2003 11:45 am 
Hibernate Team
Hibernate Team

Joined: Tue Aug 26, 2003 12:50 pm
Posts: 5130
Location: Melbourne, Australia
I suggest you put a breakpoint in Hibernate code near where the exception occurs. It is much easier to track down these kind of problems this way.


(This is the benefit of open source.)


Top
 Profile  
 
 Post subject:
PostPosted: Mon Dec 01, 2003 1:05 pm 
Newbie

Joined: Mon Dec 01, 2003 10:23 am
Posts: 7
I am unable to debug in my current environment. But from what I can tell it seems it is the many-to-one relationship between model.File and model.Pack that is causing the problem.

Code:
<many-to-one name="pack" column="parentItemId" class="com.primesounds.model.Pack"/>



If I remove this relationship it works.


Unfortunately that relationship is needed elsewhere.

I guess I could recompile the source with some debug-output in the offending function. What information do you need?

Regards,
Jonas


Top
 Profile  
 
 Post subject:
PostPosted: Mon Dec 01, 2003 2:53 pm 
Hibernate Team
Hibernate Team

Joined: Sun Sep 14, 2003 3:54 am
Posts: 7256
Location: Paris, France
I'm not sure this is allowed to share the same column="parentItemId" between different subclasses. You should try to rename it.

is assignable from means that the persistent class must be a superclass or an interface of the class you give to hibernate as load parameter

_________________
Emmanuel


Top
 Profile  
 
 Post subject:
PostPosted: Tue Dec 02, 2003 9:39 am 
Newbie

Joined: Mon Dec 01, 2003 10:23 am
Posts: 7
Quote:
I'm not sure this is allowed to share the same column="parentItemId" between different subclasses. You should try to rename it.


That was the problem. Apparently that is not allowed. I renamed parentItemId to packId and volumeId and changed all parentItemId references to their corresponding column and now it works.

It gives me more redundant data in the table but its problaby a cleaner approach.

Thanks for your help! Hibernate Forum is outstanding.


Top
 Profile  
 
 Post subject:
PostPosted: Tue Dec 02, 2003 10:22 am 
Hibernate Team
Hibernate Team

Joined: Tue Aug 26, 2003 12:50 pm
Posts: 5130
Location: Melbourne, Australia
No, this is allowed. I just tested this mapping:


Code:
<class name="org.hibernate.test.A" discriminator-value="0" lazy="true">
      <id name="id" column="identifier_column" unsaved-value = "null">
         <generator class="increment"/>
      </id>
      <discriminator column="clazz_discriminata" type="integer" force="true" not-null="false"/>
      <property name="name"/>
      <many-to-one name="forward" class="org.hibernate.test.E" cascade="save-update" />
      <subclass name="org.hibernate.test.B" discriminator-value="null" lazy="true">
         <property name="count" column="count_"/>

         <map name="map">
            <key column="BID"/>
            <index column="MAPKEY" type="string"/>
            <element column="MAPVAL" type="int"/>
         </map>

         <subclass name="org.hibernate.test.C1" discriminator-value="1" lazy="true">
            <property name="address" column="c1"/>
            <one-to-one name="d"/>
            <many-to-one name="c2" column="c" class="org.hibernate.test.C2"/>
            <bag name="c2s" inverse="true" where="clazz_discriminata=2">
               <key column="c"/>
               <one-to-many class="org.hibernate.test.C2"/>
            </bag>
         </subclass>
         <subclass name="org.hibernate.test.C2" discriminator-value="2" lazy="true">
            <property name="address" column="c2"/>
            <many-to-one name="c1" column="c" class="org.hibernate.test.C1"/>
            <bag name="c1s" inverse="true" where="clazz_discriminata=1">
               <key column="c"/>
               <one-to-many class="org.hibernate.test.C1"/>
            </bag>
         </subclass>
      </subclass>
   </class>


And it worked perfectly for the following test:

Code:
   public void testSharedColumn() throws Exception {
      Session s = openSession();
      Transaction t = s.beginTransaction();
      C1 c1 = new C1();
      C2 c2 = new C2();
      c1.setC2(c2);
      c2.setC1(c1);
      s.save(c1); s.save(c2);
      t.commit();
      s.close();

      s = openSession();
      t = s.beginTransaction();
      List list = s.find("from B");
      assertTrue( list.size()==2 );
      t.commit();
      s.close();

      s = openSession();
      t = s.beginTransaction();
      c1 = (C1) s.createQuery("from C1").uniqueResult();
      c2 = (C2) s.createQuery("from C2").uniqueResult();
      assertTrue( c1.getC2()==c2 );
      assertTrue( c2.getC1()==c1 );
      assertTrue( c1.getC2s().contains(c2) );
      assertTrue( c2.getC1s().contains(c1) );
      t.commit();
      s.close();

      s = openSession();
      t = s.beginTransaction();
      c1 = (C1) s.get( A.class, c1.getId() );
      c2 = (C2) s.get( A.class, c2.getId() );
      assertTrue( c1.getC2()==c2 );
      assertTrue( c2.getC1()==c1 );
      assertTrue( c1.getC2s().contains(c2) );
      assertTrue( c2.getC1s().contains(c1) );
      t.commit();
      s.close();

      s = openSession();
      t = s.beginTransaction();
      s.delete(c1); s.delete(c2);
      t.commit();
      s.close();
   }


So thats not the problem!


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 8 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.