Hibernate version: 3.1.2, Hibernate Annotations: 3.1b8
Name and version of the database you are using: Postgresql 8.1
I'm having a bit of a strange problem with polymorphism. I have an abstract base class Message and 2 concrete subclasses Post and Reply. Each message references the Post that began the message thread, and the setup looks something like this:
Code:
@Entity
@Inheritance(strategy = InheritanceType.JOINED)
public abstract class Message extends VO {
...
public abstract Post getThread();
...
}
@Entity
public class Post extends Message {
...
public Post getThread(){
return this;
}
...
}
@Entity
public class Reply extends Message {
@ManyToOne(optional = false)
private Post thread;
...
public Post getThread(){
return thread;
}
}
VO is a @MappedSuperclass by the way with some basic values that most of my persistent objects share (id, equals() and hashcode(), etc).
The problem arises when I retrieve a thread without yet knowing what type of message it is, i.e.
Message message = session.load(Message.class, id);
If the message is a Post and I call message.getThread(); All of a sudden I get a ClassCastException (stack trace to follow). It seems like hibernate is retrieving a CGLIB proxy of type Message for the load call and then the proxy grabs itself from the session cache when it intercepts the getThread() method call. This can't be the correct behaviour. I understand that proxy objects that reside in collections have this type of behaviour, but why would a call to session.load() not return the concrete subclass? After all I'm fairly sure it knows what the correct type is because it would be proxying it. Can anybody help me out with this?
Code:
java.lang.ClassCastException: sdc.board.Message$$EnhancerByCGLIB$$15c72c09
at sdc.board.Message$$EnhancerByCGLIB$$15c72c09.getThread(<generated>)
at sdc.control.board.main.ReplyController.referenceData(ReplyController.
java:48)
at org.springframework.web.servlet.mvc.AbstractFormController.showForm(A
bstractFormController.java:527)
at org.springframework.web.servlet.mvc.SimpleFormController.showForm(Sim
pleFormController.java:193)
at org.springframework.web.servlet.mvc.SimpleFormController.showForm(Sim
pleFormController.java:172)
at org.springframework.web.servlet.mvc.AbstractFormController.showNewFor
m(AbstractFormController.java:310)
at org.springframework.web.servlet.mvc.AbstractFormController.handleRequ
estInternal(AbstractFormController.java:250)
at org.springframework.web.servlet.mvc.AbstractController.handleRequest(
AbstractController.java:139)
at org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter.ha
ndle(SimpleControllerHandlerAdapter.java:44)
at org.springframework.web.servlet.DispatcherServlet.doDispatch(Dispatch
erServlet.java:684)
at org.springframework.web.servlet.DispatcherServlet.doService(Dispatche
rServlet.java:625)
at org.springframework.web.servlet.FrameworkServlet.serviceWrapper(Frame
workServlet.java:386)
at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServl
et.java:346)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:689)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:802)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(Appl
icationFilterChain.java:252)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationF
ilterChain.java:173)
at com.iradix.validation.ValidationFilter.doFilter(ValidationFilter.java
:62)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(Appl
icationFilterChain.java:202)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationF
ilterChain.java:173)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperV
alve.java:213)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextV
alve.java:178)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.j
ava:126)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.j
ava:105)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineVal
ve.java:107)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.jav
a:148)
at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java
:856)
at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.proce
ssConnection(Http11Protocol.java:744)
at org.apache.tomcat.util.net.PoolTcpEndpoint.processSocket(PoolTcpEndpo
int.java:527)
at org.apache.tomcat.util.net.LeaderFollowerWorkerThread.runIt(LeaderFol
lowerWorkerThread.java:80)
at org.apache.tomcat.util.threads.ThreadPool$ControlRunnable.run(ThreadP
ool.java:684)
at java.lang.Thread.run(Thread.java:613)