|
From: <leg...@at...> - 2003-09-01 11:24:28
|
Message:
The following issue has been closed.
Resolver: Gavin King
Date: Mon, 1 Sep 2003 6:23 AM
This is not a bug. This is correct behaviour.
---------------------------------------------------------------------
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: Closed
Priority: Major
Resolution: REJECTED
Project: Hibernate2
Components:
core
Versions:
2.0.2
2.0.3
Assignee:
Reporter: Marko Nikolic
Created: Sun, 31 Aug 2003 10:31 AM
Updated: Mon, 1 Sep 2003 6:23 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
|