I'm using Hibernate in a (remote) stateless session bean, and I'm getting a NullPointerException as the client tries to deserialize the object graph.
The two relevant persistent Objects are a Section, which has a bidirectional one-to-many to SectionBooks. (A SectionBook then has a many-to-one with a Book, but I don't believe the Book is relevant here).
The NullPointerException is occurring during deserialization when HashMap calls SectionBook.hashCode(), which calls Section.hashCode(). Here's the shortened stack trace (the full one is further down):
Code:
java.lang.NullPointerException
at com.classgrabber.model.Section.hashCode(Section.java:259)
at com.classgrabber.model.SectionBook.hashCode(SectionBook.java:90)
at java.util.HashMap.hash(HashMap.java:261)
at java.util.HashMap.putForCreate(HashMap.java:404)
at java.util.HashMap.readObject(HashMap.java:1007)
The SectionBook object (and table) is really just a many-to-many link table, but I'm using two one-to-many mappings as suggested in HIA. The hashCode() method of SectionBook delegates to the Objects it references on the one- side (a Section and a Book):
Code:
public int hashCode() {
int result = getSection().hashCode();
result = 29 * result + getBook().hashCode();
return result;
}
I've read HIA, and all the FAQs on the web site and I am stumped. I've seen the FAQ
http://www.hibernate.org/117.html but I don't think that applies here, because everything works fine on the server-side (the object graph can be traversed); it's only when deserializing that the problem happens. Let me know if additional information is required. Thanks for your help,
-Chris
---------------------------------------------------------
Hibernate version: 2.1.6 under JBoss 4.0.0
Mapping documents:Code:
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping
PUBLIC "-//Hibernate/Hibernate Mapping DTD//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-2.0.dtd">
<hibernate-mapping package="com.classgrabber.model">
<class name="Section" table="section">
<id name="id" type="integer" unsaved-value="null" column="id">
<generator class="native"/>
</id>
<property name="key" column="coursekey" />
<property name="instructor" />
<property name="seating" />
<property name="valid" />
<property name="open" />
<property name="waitlisted" />
<property name="flags" type="integer" />
<many-to-one name="semester" column="semesterid" class="Semester"/>
<many-to-one name="course" column="courseid" class="Course"/>
<set name="sectionBooks" table="sectionbook" cascade="delete" inverse="true" order-by="id asc" lazy="true">
<key column="sectionid"/>
<one-to-many class="SectionBook"/>
</set>
</class>
</hibernate-mapping>
<hibernate-mapping package="com.classgrabber.model">
<class name="SectionBook" table="sectionbook">
<id name="id" type="integer" unsaved-value="null" column="id">
<generator class="native"/>
</id>
<property name="authorityURL" column="authorityURL" />
<property name="status" column="book_status" />
<property name="required" type="boolean" />
<many-to-one name="section" column="sectionid" class="Section" />
<many-to-one name="book" column="bookid" class="Book"/>
</class>
</hibernate-mapping>
Code between sessionFactory.openSession() and session.close():// This method is in a remote stateless session bean:
Code:
List sections = new ArrayList();
for (Iterator it = keys.iterator(); it.hasNext();) {
String key = (String) it.next();
Integer semesterId = new Integer(14); // hardcoded for test
// Next line calls a query "from Section section where section.semester.id = :semesterid and section.key = :key"
Section sv = getSection(key, semesterId);
Hibernate.initialize(sv.getSectionBooks()); // *** This causes the exception below ****
// I need the above call, otherwise I get a LazyInitializationException
// on the client side
sections.add(sv);
}
return sections;
Full stack trace of any exception that occurs:// This happens on the client. No exception occurs in the session bean.
Code:
java.lang.NullPointerException
at com.classgrabber.model.Section.hashCode(Section.java:259)
at com.classgrabber.model.SectionBook.hashCode(SectionBook.java:90)
at java.util.HashMap.hash(HashMap.java:261)
at java.util.HashMap.putForCreate(HashMap.java:404)
at java.util.HashMap.readObject(HashMap.java:1007)
at sun.reflect.GeneratedMethodAccessor2.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.io.ObjectStreamClass.invokeReadObject(ObjectStreamClass.java:838)
at java.io.ObjectInputStream.readSerialData(ObjectInputStream.java:1746)
at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1646)
at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1274)
at java.io.ObjectInputStream.defaultReadFields(ObjectInputStream.java:1845)
at java.io.ObjectInputStream.readSerialData(ObjectInputStream.java:1769)
at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1646)
at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1274)
at java.io.ObjectInputStream.defaultReadFields(ObjectInputStream.java:1845)
at java.io.ObjectInputStream.readSerialData(ObjectInputStream.java:1769)
at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1646)
at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1274)
at java.io.ObjectInputStream.defaultReadFields(ObjectInputStream.java:1845)
at java.io.ObjectInputStream.readSerialData(ObjectInputStream.java:1769)
at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1646)
at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1274)
at java.io.ObjectInputStream.readObject(ObjectInputStream.java:324)
at java.util.ArrayList.readObject(ArrayList.java:547)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.io.ObjectStreamClass.invokeReadObject(ObjectStreamClass.java:838)
at java.io.ObjectInputStream.readSerialData(ObjectInputStream.java:1746)
at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1646)
at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1274)
at java.io.ObjectInputStream.defaultReadFields(ObjectInputStream.java:1845)
at java.io.ObjectInputStream.readSerialData(ObjectInputStream.java:1769)
at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1646)
at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1274)
at java.io.ObjectInputStream.readObject(ObjectInputStream.java:324)
at java.rmi.MarshalledObject.get(MarshalledObject.java:135)
at org.jboss.invocation.jrmp.interfaces.JRMPInvokerProxy.invoke(JRMPInvokerProxy.java:119)
at org.jboss.invocation.InvokerInterceptor.invoke(InvokerInterceptor.java:96)
at org.jboss.proxy.TransactionInterceptor.invoke(TransactionInterceptor.java:46)
at org.jboss.proxy.SecurityInterceptor.invoke(SecurityInterceptor.java:55)
at org.jboss.proxy.ejb.StatelessSessionInterceptor.invoke(StatelessSessionInterceptor.java:97)
at org.jboss.proxy.ClientContainer.invoke(ClientContainer.java:86)
at $Proxy3.getBookDetails(Unknown Source)
at com.classgrabber.hibernate.BookManagerHibernateDelegate.getBookDetails(BookManagerHibernateDelegate.java:133)
at com.classgrabber.persistence.TestBookManager.testGetSectionBookDetails(TestBookManager.java:168)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at com.intellij.rt.execution.junit2.JUnitStarter.main(JUnitStarter.java:31)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:78)
Name and version of the database you are using:
MySQL 4.1.7
The generated SQL (show_sql=true):
(IF this is relevant tell me and I'll post it)
Debug level Hibernate log excerpt:
(It's over 1000 lines long, if it's relevant I'll post it)