I'm getting a NullPointerException when trying to merge or saveOrUpdate a parent object that has cascade="all, delete-orphan" specified on a collection of objects mapped with a composite id that includes a key-many-to-one. I'm using Hibernate 3.2.1ga with jdk1.5.0_09.
Here's the code:
Code:
package com.foo.persist;
import java.util.Set;
public class Parent {
private Long internalId;
private String parentId;
private Set<ContactIssue> contactIssueSet;
private Integer version;
public Long getInternalId() {
return internalId;
}
public void setInternalId(Long internalId) {
this.internalId = internalId;
}
public String getParentId() {
return parentId;
}
public void setParentId(String parentId) {
this.parentId = parentId;
}
public Integer getVersion() {
return version;
}
public void setVersion(Integer version) {
this.version = version;
}
public Set<ContactIssue> getContactIssueSet() {
return contactIssueSet;
}
public void setContactIssueSet(Set<ContactIssue> contactIssueSet) {
this.contactIssueSet = contactIssueSet;
}
}
package com.foo.persist;
import java.io.Serializable;
import java.util.Date;
public class ContactIssue implements Serializable {
/**
*
*/
private static final long serialVersionUID = 1L;
private Contact contact;
private Date dateTime;
private Parent parent;
private Integer version;
public Contact getContact() {
return contact;
}
public void setContact(Contact contact) {
this.contact = contact;
}
public Date getDateTime() {
return dateTime;
}
public void setDateTime(Date dateTime) {
this.dateTime = dateTime;
}
public Parent getParent() {
return parent;
}
public void setParent(Parent parent) {
this.parent = parent;
}
public Integer getVersion() {
return version;
}
public void setVersion(Integer version) {
this.version = version;
}
}
package com.foo.persist;
public class Contact {
private Long internalId;
private String name;
private Integer version;
public Long getInternalId() {
return internalId;
}
public void setInternalId(Long internalId) {
this.internalId = internalId;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getVersion() {
return version;
}
public void setVersion(Integer version) {
this.version = version;
}
}
package com.foo.test;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.sql.SQLException;
import java.util.Date;
import java.util.HashSet;
import org.dbunit.DatabaseUnitException;
import org.hibernate.Session;
import org.hibernate.Transaction;
import com.foo.persist.Contact;
import com.foo.persist.ContactIssue;
import com.foo.persist.Parent;
import com.foo.util.HibernateSessionFactory;
public class Test {
/**
* @param args
* @throws IOException
* @throws FileNotFoundException
* @throws SQLException
* @throws DatabaseUnitException
*/
@SuppressWarnings("unchecked")
public static void main(String[] args) throws FileNotFoundException, IOException, DatabaseUnitException, SQLException {
Parent lParent = new Parent();
lParent.setParentId("PARENT1");
HashSet<ContactIssue> lContactIssueSet = new HashSet<ContactIssue>();
ContactIssue lContactIssue = new ContactIssue();
Contact lContact = new Contact();
lContact.setName("CONTACT1");
lContactIssue.setContact(lContact);
lContactIssue.setDateTime(new Date());
lContactIssue.setParent(lParent);
lContactIssueSet.add(lContactIssue);
lParent.setContactIssueSet(lContactIssueSet);
Session lSession = HibernateSessionFactory.getSession();
Transaction t = lSession.beginTransaction();
lSession.merge(lParent);
t.commit();
HibernateSessionFactory.closeSession();
}
}
Here's the mapping files:
Code:
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="com.foo.persist">
<class name="Parent" table="PAR_PARENT" lazy="true">
<id column="PAR_UID" name="internalId" type="long">
<generator class="native" />
</id>
<version name="version" column="PAR_VERSION" />
<property column="PAR_ID" name="parentId" type="string"
length="32">
</property>
<set name="contactIssueSet" inverse="false" cascade="all, delete-orphan">
<key column="COI_PAR_UID"/>
<one-to-many class="ContactIssue"/>
</set>
</class>
</hibernate-mapping>
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="com.foo.persist">
<class name="ContactIssue" table="COI_CONTACT_ISSUE" lazy="true">
<composite-id>
<key-many-to-one
name="contact"
class="Contact"
>
<column name="COI_CON_UID" not-null="true" />
</key-many-to-one>
<key-property
name="dateTime"
type="java.util.Date"
>
<column name="COI_TIMESTAMP" not-null="true" />
</key-property>
</composite-id>
<version name="version" column="COI_VERSION" />
<many-to-one
column="COI_PAR_UID"
name="parent"
class="Parent"
/>
</class>
</hibernate-mapping>
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="com.foo.persist">
<class name="Contact" table="CON_CONTACT" lazy="true">
<id column="CON_UID" name="internalId" type="long">
<generator class="native" />
</id>
<version name="version" column="CON_VERSION" />
<property name="name" column="CON_NAME" type="string" length="32"/>
</class>
</hibernate-mapping>
And here's the stacktrace:
Quote:
Exception in thread "main" java.lang.NullPointerException
at org.hibernate.type.AbstractType.getHashCode(AbstractType.java:112)
at org.hibernate.type.AbstractType.getHashCode(AbstractType.java:120)
at org.hibernate.type.EntityType.getHashCode(EntityType.java:279)
at org.hibernate.type.ComponentType.getHashCode(ComponentType.java:189)
at org.hibernate.engine.EntityKey.generateHashCode(EntityKey.java:104)
at org.hibernate.engine.EntityKey.<init>(EntityKey.java:48)
at org.hibernate.event.def.DefaultMergeEventListener.onMerge(DefaultMergeEventListener.java:100)
at org.hibernate.impl.SessionImpl.fireMerge(SessionImpl.java:687)
at org.hibernate.impl.SessionImpl.merge(SessionImpl.java:669)
at org.hibernate.engine.CascadingAction$6.cascade(CascadingAction.java:245)
at org.hibernate.engine.Cascade.cascadeToOne(Cascade.java:268)
at org.hibernate.engine.Cascade.cascadeAssociation(Cascade.java:216)
at org.hibernate.engine.Cascade.cascadeProperty(Cascade.java:169)
at org.hibernate.engine.Cascade.cascadeCollectionElements(Cascade.java:296)
at org.hibernate.engine.Cascade.cascadeCollection(Cascade.java:242)
at org.hibernate.engine.Cascade.cascadeAssociation(Cascade.java:219)
at org.hibernate.engine.Cascade.cascadeProperty(Cascade.java:169)
at org.hibernate.engine.Cascade.cascade(Cascade.java:130)
at org.hibernate.event.def.AbstractSaveEventListener.cascadeAfterSave(AbstractSaveEventListener.java:437)
at org.hibernate.event.def.DefaultMergeEventListener.entityIsTransient(DefaultMergeEventListener.java:194)
at org.hibernate.event.def.DefaultMergeEventListener.onMerge(DefaultMergeEventListener.java:123)
at org.hibernate.event.def.DefaultMergeEventListener.onMerge(DefaultMergeEventListener.java:53)
at org.hibernate.impl.SessionImpl.fireMerge(SessionImpl.java:677)
at org.hibernate.impl.SessionImpl.merge(SessionImpl.java:661)
at org.hibernate.impl.SessionImpl.merge(SessionImpl.java:665)
at com.foo.test.Test.main(Test.java:44)
I'm looking for a cascading merge from Parent->ContactIssue->Contact.