I have found what appears to be a bug in Hibernate.
I have an entity class, PostedMessage, that extends another entity class, Message:
Code:
@Entity
@Inheritance(strategy=JOINED)
public class Message
{
private Long id;
private Date whenSent = new Date();
@Id
@GeneratedValue(strategy=AUTO)
public Long getId()
{
return id;
}
public void setId(Long id)
{
this.id = id;
}
@Temporal(TIMESTAMP)
@Basic(optional=false)
public Date getWhenSent()
{
return whenSent;
}
public void setWhenSent(Date whenSent)
{
this.whenSent = whenSent;
}
}
@Entity
public class PostedMessage extends Message
{
private DiscussionThread thread;
private PostedMessage parent;
private Collection<PostedMessage> replies = new LinkedList<PostedMessage>();
@ManyToOne
public PostedMessage getParent()
{
return parent;
}
public void setParent(PostedMessage parent)
{
this.parent = parent;
}
@ManyToOne(optional=false)
public DiscussionThread getThread()
{
return thread;
}
public void setThread(DiscussionThread thread)
{
this.thread = thread;
}
@OneToMany(mappedBy="parent")
@OrderBy("whenSent")
public Collection<PostedMessage> getReplies()
{
return replies;
}
public void setReplies(List<PostedMessage> replies)
{
this.replies = replies;
}
}
(I've omitted fields that are not relevant to this problem.)
When I try to access the "replies" collection, it generates this SQL:
Code:
select replies0_.parent_id as parent2_6_, replies0_.id as id6_, replies0_.id as id1_5_, replies0_1_.author_id as author7_1_5_, replies0_1_.body as body1_5_, replies0_1_.contentType as contentT3_1_5_, replies0_1_.lastModified as lastModi4_1_5_, replies0_1_.subject as subject1_5_, replies0_1_.whenSent as whenSent1_5_, replies0_.parent_id as parent2_5_5_, replies0_.thread_id as thread3_5_5_, author1_.id as id3_0_, author1_.emailAddress as emailAdd2_3_0_, author1_.fullName as fullName3_0_, author1_1_.rawAddress as rawAddress4_0_, author1_2_.name as name7_0_, author1_2_.password as password7_0_, case when author1_1_.id is not null then 1 when author1_2_.id is not null then 2 when author1_.id is not null then 0 end as clazz_0_, discussion2_.id as id0_1_, discussion2_.firstMessage_id as firstMes2_0_1_, discussion2_.forum_id as forum3_0_1_, discussion2_.lastMessage_id as lastMess4_0_1_, postedmess3_.id as id1_2_, postedmess3_1_.author_id as author7_1_2_, postedmess3_1_.body as body1_2_, postedmess3_1_.contentType as contentT3_1_2_, postedmess3_1_.lastModified as lastModi4_1_2_, postedmess3_1_.subject as subject1_2_, postedmess3_1_.whenSent as whenSent1_2_, postedmess3_.parent_id as parent2_5_2_, postedmess3_.thread_id as thread3_5_2_, forum4_.id as id6_3_, forum4_.canonicalName as canonica2_6_3_, forum4_.description as descript3_6_3_, forum4_.name as name6_3_, forum4_.parent_id as parent5_6_3_, postedmess5_.id as id1_4_, postedmess5_1_.author_id as author7_1_4_, postedmess5_1_.body as body1_4_, postedmess5_1_.contentType as contentT3_1_4_, postedmess5_1_.lastModified as lastModi4_1_4_, postedmess5_1_.subject as subject1_4_, postedmess5_1_.whenSent as whenSent1_4_, postedmess5_.parent_id as parent2_5_4_, postedmess5_.thread_id as thread3_5_4_ from PostedMessage replies0_ inner join Message replies0_1_ on replies0_.id=replies0_1_.id inner join Author author1_ on replies0_1_.author_id=author1_.id left outer join GuestAuthor author1_1_ on author1_.id=author1_1_.id left outer join User author1_2_ on author1_.id=author1_2_.id inner join DiscussionThread discussion2_ on replies0_.thread_id=discussion2_.id left outer join PostedMessage postedmess3_ on discussion2_.firstMessage_id=postedmess3_.id left outer join Message postedmess3_1_ on postedmess3_.id=postedmess3_1_.id left outer join Forum forum4_ on discussion2_.forum_id=forum4_.id left outer join PostedMessage postedmess5_ on discussion2_.lastMessage_id=postedmess5_.id left outer join Message postedmess5_1_ on postedmess5_.id=postedmess5_1_.id where replies0_.parent_id=? order by Message.whenSent asc
which results in this exception trace:
Code:
org.springframework.web.util.NestedServletException: Request processing failed; nested exception is org.hibernate.exception.SQLGrammarException: could not initialize a collection: [org.frecklepuppy.bb.model.PostedMessage.replies#1]
org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:535)
org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:453)
javax.servlet.http.HttpServlet.service(HttpServlet.java:690)
javax.servlet.http.HttpServlet.service(HttpServlet.java:803)
root cause
org.hibernate.exception.SQLGrammarException: could not initialize a collection: [org.frecklepuppy.bb.model.PostedMessage.replies#1]
org.hibernate.exception.SQLStateConverter.convert(SQLStateConverter.java:67)
org.hibernate.exception.JDBCExceptionHelper.convert(JDBCExceptionHelper.java:43)
org.hibernate.loader.Loader.loadCollection(Loader.java:2001)
org.hibernate.loader.collection.CollectionLoader.initialize(CollectionLoader.java:36)
org.hibernate.persister.collection.AbstractCollectionPersister.initialize(AbstractCollectionPersister.java:565)
org.hibernate.event.def.DefaultInitializeCollectionEventListener.onInitializeCollection(DefaultInitializeCollectionEventListener.java:63)
org.hibernate.impl.SessionImpl.initializeCollection(SessionImpl.java:1716)
org.hibernate.collection.AbstractPersistentCollection.initialize(AbstractPersistentCollection.java:344)
org.hibernate.collection.AbstractPersistentCollection.read(AbstractPersistentCollection.java:86)
org.hibernate.collection.PersistentBag.iterator(PersistentBag.java:249)
org.frecklepuppy.bb.service.impl.ThreadLookupServiceImpl.forceLoadMessage(ThreadLookupServiceImpl.java:33)
org.frecklepuppy.bb.service.impl.ThreadLookupServiceImpl.findThreadById(ThreadLookupServiceImpl.java:26)
sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
java.lang.reflect.Method.invoke(Method.java:597)
org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:310)
org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:182)
org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:149)
org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:106)
org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:171)
org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:204)
$Proxy31.findThreadById(Unknown Source)
org.frecklepuppy.bb.ui.controllers.ViewThreadController.viewThread(ViewThreadController.java:37)
sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
java.lang.reflect.Method.invoke(Method.java:597)
org.springframework.web.bind.annotation.support.HandlerMethodInvoker.doInvokeMethod(HandlerMethodInvoker.java:413)
org.springframework.web.bind.annotation.support.HandlerMethodInvoker.invokeHandlerMethod(HandlerMethodInvoker.java:134)
org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter.invokeHandlerMethod(AnnotationMethodHandlerAdapter.java:310)
org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter.handle(AnnotationMethodHandlerAdapter.java:297)
org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:875)
org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:809)
org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:523)
org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:453)
javax.servlet.http.HttpServlet.service(HttpServlet.java:690)
javax.servlet.http.HttpServlet.service(HttpServlet.java:803)
root cause
com.mysql.jdbc.exceptions.MySQLSyntaxErrorException: Unknown column 'Message.whenSent' in 'order clause'
com.mysql.jdbc.SQLError.createSQLException(SQLError.java:936)
com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:2870)
com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:1573)
com.mysql.jdbc.MysqlIO.sqlQueryDirect(MysqlIO.java:1665)
com.mysql.jdbc.Connection.execSQL(Connection.java:3176)
com.mysql.jdbc.PreparedStatement.executeInternal(PreparedStatement.java:1153)
com.mysql.jdbc.PreparedStatement.executeQuery(PreparedStatement.java:1266)
org.apache.tomcat.dbcp.dbcp.DelegatingPreparedStatement.executeQuery(DelegatingPreparedStatement.java:93)
org.hibernate.jdbc.AbstractBatcher.getResultSet(AbstractBatcher.java:186)
org.hibernate.loader.Loader.getResultSet(Loader.java:1787)
org.hibernate.loader.Loader.doQuery(Loader.java:674)
org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:236)
org.hibernate.loader.Loader.loadCollection(Loader.java:1994)
org.hibernate.loader.collection.CollectionLoader.initialize(CollectionLoader.java:36)
org.hibernate.persister.collection.AbstractCollectionPersister.initialize(AbstractCollectionPersister.java:565)
org.hibernate.event.def.DefaultInitializeCollectionEventListener.onInitializeCollection(DefaultInitializeCollectionEventListener.java:63)
org.hibernate.impl.SessionImpl.initializeCollection(SessionImpl.java:1716)
org.hibernate.collection.AbstractPersistentCollection.initialize(AbstractPersistentCollection.java:344)
org.hibernate.collection.AbstractPersistentCollection.read(AbstractPersistentCollection.java:86)
org.hibernate.collection.PersistentBag.iterator(PersistentBag.java:249)
org.frecklepuppy.bb.service.impl.ThreadLookupServiceImpl.forceLoadMessage(ThreadLookupServiceImpl.java:33)
org.frecklepuppy.bb.service.impl.ThreadLookupServiceImpl.findThreadById(ThreadLookupServiceImpl.java:26)
sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
java.lang.reflect.Method.invoke(Method.java:597)
org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:310)
org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:182)
org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:149)
org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:106)
org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:171)
org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:204)
$Proxy31.findThreadById(Unknown Source)
org.frecklepuppy.bb.ui.controllers.ViewThreadController.viewThread(ViewThreadController.java:37)
sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
java.lang.reflect.Method.invoke(Method.java:597)
org.springframework.web.bind.annotation.support.HandlerMethodInvoker.doInvokeMethod(HandlerMethodInvoker.java:413)
org.springframework.web.bind.annotation.support.HandlerMethodInvoker.invokeHandlerMethod(HandlerMethodInvoker.java:134)
org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter.invokeHandlerMethod(AnnotationMethodHandlerAdapter.java:310)
org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter.handle(AnnotationMethodHandlerAdapter.java:297)
org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:875)
org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:809)
org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:523)
org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:453)
javax.servlet.http.HttpServlet.service(HttpServlet.java:690)
javax.servlet.http.HttpServlet.service(HttpServlet.java:803)
I verified that the "whenSent" column does exist in the "Message" table.
I'm using MySQL 5.0.18, Hibernate Core 3.2.6, Hibernate EntityManager 3.3.2, and the MySQL5InnoDBDialect.
Am I doing something wrong that I'm just not seeing, or is this a bug?