net.sf.hibernate.WrongClassException: Object with id: 1346 was not of the specified subclass: my.BarImpl(loaded object was of wrong class)

Hibernate JIRA | Sam Perman | 1 decade ago
  1. 0

    I have a table that contains elements of different types... for example: my_table ( id (a long) type (and enumerated type, eithe 'foo' or 'bar') ) they can be link together in a link table my_link_table ( parent_id child_id ) I have three mappings (one parent, and two subclasses): <hibernate-mapping> <class name="my.ParentImpl" table="my_table" discriminator-value="null" mutable="false"> <cache usage="read-only"/> <id name="mId" column="id" type="long" access="field"> <generator class="sequence"> <param name="sequence">foo_seq</param> </generator> </id> <discriminator column="type" type="string"/> <subclass name="my.FooImpl" discriminator-value="foo"> </subclass> <subclass name="my.BarImpl" disciminator-value="bar"> <set name="parentFoos" table="my_link_table" access="field" lazy="true"> <key column="child_id"/> <many-to-many column="parent_id" class="my.FooImpl"/> </set> </subclass> </hibernate-mapping> At this point, I load an instance of BarImpl and I access the "parentFoos" collection. My hope is that it only reads values from "my_link_table" if the object referenced by "parent_id" has the correct discriminator-value. Unfortunately, even if the parent_id has a discriminator-value of "bar" it will read it from the database AND create a FooImpl with that data. This results in an entry in the cache where there is a FooImpl in the cache for an id that should actually be a BarImpl. This means that the next time I get the BarImpl, I get the following exception: ERROR 2004-05-27 15:05:59,453 my.FooService - Unable to retrieve related styles for: my.BarImpl@2d4c7e net.sf.hibernate.WrongClassException: Object with id: 1346 was not of the specified subclass: my.BarImpl(loaded object was of wrong class) at net.sf.hibernate.loader.Loader.instanceAlreadyLoaded(Loader.java:456) at net.sf.hibernate.loader.Loader.getRow(Loader.java:423) at net.sf.hibernate.loader.Loader.doQuery(Loader.java:209) at net.sf.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:133) at net.sf.hibernate.loader.Loader.doList(Loader.java:955) at net.sf.hibernate.loader.Loader.list(Loader.java:946) at net.sf.hibernate.loader.SQLLoader.list(SQLLoader.java:92) at net.sf.hibernate.impl.SessionImpl.findBySQL(SessionImpl.java:3797) at net.sf.hibernate.impl.SQLQueryImpl.list(SQLQueryImpl.java:52) at my.BarImpl.getParents(BarImpl.java:266) The sql that hibernate uses to initially populate the collection is: select parentf0_.parent_id as parent_1___, parentf0_.child_id as child_2___ from my_link_table parentf0_ where parentf0_.child_id=1003 I think this should add a where clause (and an additional "from" table) something like: AND parentf0_.parent_id = my_table.parent_id AND my_table.type='foo'

    Hibernate JIRA | 1 decade ago | Sam Perman
    net.sf.hibernate.WrongClassException: Object with id: 1346 was not of the specified subclass: my.BarImpl(loaded object was of wrong class)
  2. 0

    I have a table that contains elements of different types... for example: my_table ( id (a long) type (and enumerated type, eithe 'foo' or 'bar') ) they can be link together in a link table my_link_table ( parent_id child_id ) I have three mappings (one parent, and two subclasses): <hibernate-mapping> <class name="my.ParentImpl" table="my_table" discriminator-value="null" mutable="false"> <cache usage="read-only"/> <id name="mId" column="id" type="long" access="field"> <generator class="sequence"> <param name="sequence">foo_seq</param> </generator> </id> <discriminator column="type" type="string"/> <subclass name="my.FooImpl" discriminator-value="foo"> </subclass> <subclass name="my.BarImpl" disciminator-value="bar"> <set name="parentFoos" table="my_link_table" access="field" lazy="true"> <key column="child_id"/> <many-to-many column="parent_id" class="my.FooImpl"/> </set> </subclass> </hibernate-mapping> At this point, I load an instance of BarImpl and I access the "parentFoos" collection. My hope is that it only reads values from "my_link_table" if the object referenced by "parent_id" has the correct discriminator-value. Unfortunately, even if the parent_id has a discriminator-value of "bar" it will read it from the database AND create a FooImpl with that data. This results in an entry in the cache where there is a FooImpl in the cache for an id that should actually be a BarImpl. This means that the next time I get the BarImpl, I get the following exception: ERROR 2004-05-27 15:05:59,453 my.FooService - Unable to retrieve related styles for: my.BarImpl@2d4c7e net.sf.hibernate.WrongClassException: Object with id: 1346 was not of the specified subclass: my.BarImpl(loaded object was of wrong class) at net.sf.hibernate.loader.Loader.instanceAlreadyLoaded(Loader.java:456) at net.sf.hibernate.loader.Loader.getRow(Loader.java:423) at net.sf.hibernate.loader.Loader.doQuery(Loader.java:209) at net.sf.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:133) at net.sf.hibernate.loader.Loader.doList(Loader.java:955) at net.sf.hibernate.loader.Loader.list(Loader.java:946) at net.sf.hibernate.loader.SQLLoader.list(SQLLoader.java:92) at net.sf.hibernate.impl.SessionImpl.findBySQL(SessionImpl.java:3797) at net.sf.hibernate.impl.SQLQueryImpl.list(SQLQueryImpl.java:52) at my.BarImpl.getParents(BarImpl.java:266) The sql that hibernate uses to initially populate the collection is: select parentf0_.parent_id as parent_1___, parentf0_.child_id as child_2___ from my_link_table parentf0_ where parentf0_.child_id=1003 I think this should add a where clause (and an additional "from" table) something like: AND parentf0_.parent_id = my_table.parent_id AND my_table.type='foo'

    Hibernate JIRA | 1 decade ago | Sam Perman
    net.sf.hibernate.WrongClassException: Object with id: 1346 was not of the specified subclass: my.BarImpl(loaded object was of wrong class)
  3. 0

    Hello folks, I did not find anything related to this issue on the net so I put it here: Provided are two classes A and B wich are in a 1.) many-to-many relationship 2.) with an association class Association which contains some forther attributes 2.) and is navigable from A to B and from B to A I thried to implement this in hibernate and it works well as long as the navigation goes only in one direction meaning: there is 1.) a public Collection getABAssociatins() method in the A class 2.) a public B getB() method in the Association class At the point where I try to include backwards navigation I run into the following error stack: net.sf.hibernate.WrongClassException: Object with id: 21 was not of the specified subclass: test.A (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.loadCollection(Loader.java:602) at net.sf.hibernate.loader.OneToManyLoader.initialize(OneToManyLoader.java:102) at net.sf.hibernate.impl.SessionImpl.initialize(SessionImpl.java:2897) at net.sf.hibernate.collection.PersistentCollection.getInitialValue(PersistentCollection.java:128) at net.sf.hibernate.type.PersistentCollectionType.getCollection(PersistentCollectionType.java:74) at net.sf.hibernate.type.PersistentCollectionType.resolveIdentifier(PersistentCollectionType.java:177) at net.sf.hibernate.impl.SessionImpl.initializeEntity(SessionImpl.java:1959) at net.sf.hibernate.loader.Loader.doFind(Loader.java:196) at net.sf.hibernate.loader.Loader.loadCollection(Loader.java:602) at net.sf.hibernate.loader.OneToManyLoader.initialize(OneToManyLoader.java:102) at net.sf.hibernate.impl.SessionImpl.initialize(SessionImpl.java:2897) at net.sf.hibernate.collection.PersistentCollection.getInitialValue(PersistentCollection.java:128) at net.sf.hibernate.type.PersistentCollectionType.getCollection(PersistentCollectionType.java:74) at net.sf.hibernate.type.PersistentCollectionType.resolveIdentifier(PersistentCollectionType.java:177) at net.sf.hibernate.impl.SessionImpl.initializeEntity(SessionImpl.java:1959) at net.sf.hibernate.loader.Loader.doFind(Loader.java:196) 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.load(SessionImpl.java:1688) at test.testEnitityToObjectToEntityReferenzes(HibernateTest.java:315) I suppose hibernat does not support this kind of usage (or am I doing something wrong???) and would like to propose this for an improvement. Kindest Regards Alexander Thomas

    Hibernate JIRA | 1 decade ago | alexander thomas
    net.sf.hibernate.WrongClassException: Object with id: 21 was not of the specified subclass: test.A (loaded object was of wrong class)
  4. Speed up your debug routine!

    Automated exception search integrated into your IDE

  5. 0

    I have 2 classes, Product (for core product info) and DisplayProduct (has extra fields) which is a subclass of Product. Display product is read only & used as a data aggregation class, i *could* load the product instance & then copy to a DisplayProduct instance, but it means 2x overhead for something desired to be an optimisation, i.e. not a great solution. What happens is the loader gets confused & after loading an instance of one class, i can not load an instance of the other, yes they are both mapped to one table, share the same key & one is a subclass, but they are not the same object in the context of the application. I get the following error: <snip> net.sf.hibernate.WrongClassException: Object with id: XXX was not of the specified subclass: com.woolly.store.product.DisplayProduct (loaded object was of wrong class) at net.sf.hibernate.loader.Loader.instanceAlreadyLoaded(Loader.java:531) </snip> samplecode from classes: class Product { private String code; private String description; ... //getters/setters etc ... } and; class DisplayProduct extends Product { private List images; private BigDecimal price; ... //getters/setters etc ... } If i map both of these classes to the same table; <class name="Product" table="str_products"> <id name="code" unsaved-value="null"> <generator class="assigned"/> </id> <version name="version" type="int"/> <property name="name"/> <property name="description"/> <property name="taxCode"/> ... </class> and <class name="DisplayProduct" table="str_products" mutable="false"> <id name="code" unsaved-value="null"> <generator class="assigned"/> </id> <property name="name"/> <property name="description"/> <property name="taxCode"/> ... </class> I have tried switching off the secondary level cache, but the problem seems to run deeper than this. (assuming that setting hibernate.cache.use_second_level_cache=false to do this.) Ideas?

    Hibernate JIRA | 1 decade ago | Dave Birch
    net.sf.hibernate.WrongClassException: Object with id: XXX was not of the specified subclass: com.woolly.store.product.DisplayProduct (loaded object was of wrong class)
  6. 0

    I am having problem using Lightweight design pattern. I must admit that I am completely new to Hibernate but it seems to me like this is a bug of Hibernate. Here are my mappings: ### FileInfo.hbm.xml ### <?xml version="1.0"?> <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 2.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-2.0.dtd"> <hibernate-mapping> <class name="com.redstarshop.data.FileInfo" table="files"> <id name="id" column="id" type="long"> <generator class="native"/> </id> <property name="name" column="name"/> <property name="contentType" column="content_type" not-null="true"/> <property name="length" not-null="true" column="content_length"/> <property name="lastModified" column="last_modified" not-null="true"/> </class> </hibernate-mapping> ### File.hbm.xml ### <?xml version="1.0"?> <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 2.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-2.0.dtd"> <hibernate-mapping> <class name="com.redstarshop.data.File" table="files" polymorphism="explicit"> <id name="id" column="id" type="long"> <generator class="native"/> </id> <property name="name" column="name"/> <property name="contentType" column="content_type" not-null="true"/> <property name="length" not-null="true" column="content_length"/> <property name="lastModified" column="last_modified" not-null="true"/> <property name="content" not-null="true"/> </class> </hibernate-mapping> ### End of mappings ### Now, loading FileInfo (lightweight) entity works fine. But if I try to load File (heavyweight) entity (after FileInfo was loaded and cached) with the same id as loaded FileInfo, using either: session.load(File.class, id) or session.find("from com.redstarshop.data.File as c where c.id = ?", id, Hibernate.LONG) I always get net.sf.hibernate.WrongClassException: Object with id: 12 was not of the specified subclass: com.redstarshop.data.File (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.find(Loader.java:620) at net.sf.hibernate.hql.QueryTranslator.find(QueryTranslator.java:928) at net.sf.hibernate.impl.SessionImpl.find(SessionImpl.java:1343) at net.sf.hibernate.impl.SessionImpl.find(SessionImpl.java:1322) at net.sf.hibernate.impl.SessionImpl.find(SessionImpl.java:1318) at com.redstarshop.util.Utils.findOne(Utils.java:46) at com.redstarshop.tapestry.FileService.service(FileService.java:116) at org.apache.tapestry.engine.AbstractEngine.service(AbstractEngine.java:913) at org.apache.tapestry.ApplicationServlet.doService(ApplicationServlet.java:238) at org.apache.tapestry.ApplicationServlet.doGet(ApplicationServlet.java:199) at javax.servlet.http.HttpServlet.service(HttpServlet.java:740) at javax.servlet.http.HttpServlet.service(HttpServlet.java:853) at org.mortbay.jetty.servlet.ServletHolder.handle(ServletHolder.java:366) at org.mortbay.jetty.servlet.WebApplicationHandler$Chain.doFilter(WebApplicationHandler.java:341) at org.apache.tapestry.RedirectFilter.doFilter(RedirectFilter.java:148) at org.mortbay.jetty.servlet.WebApplicationHandler$Chain.doFilter(WebApplicationHandler.java:333) at org.mortbay.jetty.servlet.WebApplicationHandler.dispatch(WebApplicationHandler.java:285) at org.mortbay.jetty.servlet.ServletHandler.handle(ServletHandler.java:567) at org.mortbay.http.HttpContext.handle(HttpContext.java:1696) at org.mortbay.jetty.servlet.WebApplicationContext.handle(WebApplicationContext.java:552) at org.mortbay.http.HttpContext.handle(HttpContext.java:1646) at org.mortbay.http.HttpServer.service(HttpServer.java:884) at org.mortbay.http.HttpConnection.service(HttpConnection.java:799) at org.mortbay.http.HttpConnection.handleNext(HttpConnection.java:949) at org.mortbay.http.HttpConnection.handle(HttpConnection.java:816) at org.mortbay.http.SocketListener.handleConnection(SocketListener.java:204) at org.mortbay.util.ThreadedServer.handle(ThreadedServer.java:290) at org.mortbay.util.ThreadPool$PoolThread.run(ThreadPool.java:509) Following patch against 2.0.3 works fine for me (I patched loader to use fetched instance only if it is assignable to requested type). ### Begin of patch ### --- /cygdrive/c/java/hibernate-2.0.3/src/net/sf/hibernate/loader/Loader.java 2003-08-27 16:49:40.000000000 +0200 +++ hibernate-2.0.3/src/net/sf/hibernate/loader/Loader.java 2003-08-31 17:03:34.000000000 +0200 @@ -273,7 +273,7 @@ public abstract class Loader { //If the object is already loaded, return the loaded one object = session.getEntity(key); - if (object!=null) { + if (object!=null && persisters[i].getMappedClass().isAssignableFrom(object.getClass())) { //its already loaded so don't need to hydrate it instanceAlreadyLoaded(rs, i, persisters[i], suffixes[i], key, object, lockModes[i], session); } @@ -296,9 +296,6 @@ public abstract class Loader { private void instanceAlreadyLoaded(ResultSet rs, int i, Loadable persister, String suffix, Key key, Object object, LockMode lockMode, SessionImplementor session) throws HibernateException, SQLException { - if ( !persister.getMappedClass().isAssignableFrom( object.getClass() ) ) - throw new WrongClassException( "loaded object was of wrong class", key.getIdentifier(), persister.getMappedClass() ); - if ( LockMode.NONE!=lockMode && upgradeLocks() ) { //no point doing this if NONE was requested if ( ### End of patch ###

    Hibernate JIRA | 1 decade ago | Marko Nikolic
    net.sf.hibernate.WrongClassException: Object with id: 12 was not of the specified subclass: com.redstarshop.data.File (loaded object was of wrong class)

    Not finding the right solution?
    Take a tour to get the most out of Samebug.

    Tired of useless tips?

    Automated exception search integrated into your IDE

    Root Cause Analysis

    1. net.sf.hibernate.WrongClassException

      Object with id: 1346 was not of the specified subclass: my.BarImpl(loaded object was of wrong class)

      at net.sf.hibernate.loader.Loader.instanceAlreadyLoaded()
    2. net.sf.hibernate
      SQLQueryImpl.list
      1. net.sf.hibernate.loader.Loader.instanceAlreadyLoaded(Loader.java:456)
      2. net.sf.hibernate.loader.Loader.getRow(Loader.java:423)
      3. net.sf.hibernate.loader.Loader.doQuery(Loader.java:209)
      4. net.sf.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:133)
      5. net.sf.hibernate.loader.Loader.doList(Loader.java:955)
      6. net.sf.hibernate.loader.Loader.list(Loader.java:946)
      7. net.sf.hibernate.loader.SQLLoader.list(SQLLoader.java:92)
      8. net.sf.hibernate.impl.SessionImpl.findBySQL(SessionImpl.java:3797)
      9. net.sf.hibernate.impl.SQLQueryImpl.list(SQLQueryImpl.java:52)
      9 frames
    3. my
      BarImpl.getParents
      1. my.BarImpl.getParents(BarImpl.java:266)
      1 frame