From: <leg...@at...> - 2003-08-31 15:58:28
|
The following comment has been added to this issue: Author: Marko Nikolic Created: Sun, 31 Aug 2003 10:58 AM Body: Unfortunately, this patch works only for session.find, in order to make session.load work I guess that SessionImpl should be patched too. --------------------------------------------------------------------- View the issue: http://opensource.atlassian.com/projects/hibernate/secure/ViewIssue.jspa?key=HB-301 Here is an overview of the issue: --------------------------------------------------------------------- Key: HB-301 Summary: Lightweight design pattern does not work (WrongClassException) Type: Patch Status: Unassigned Priority: Major Project: Hibernate2 Components: core Versions: 2.0.2 2.0.3 Assignee: Reporter: Marko Nikolic Created: Sun, 31 Aug 2003 10:31 AM Updated: Sun, 31 Aug 2003 10:31 AM Environment: Windows XP, JDK 1.4.2, Jetty 4.2.3 Description: 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 ### --------------------------------------------------------------------- JIRA INFORMATION: This message is automatically generated by JIRA. If you think it was sent incorrectly contact one of the administrators: http://opensource.atlassian.com/projects/hibernate/secure/Administrators.jspa If you want more information on JIRA, or have a bug to report see: http://www.atlassian.com/software/jira |