package com.tnf.db.ass.mtm;
import javax.persistence.*;
import java.io.Serializable;
@Entity
@Table(name="PROJECT_X_PERSON")
@IdClass(ProjectXPerson.PK.class)
public class ProjectXPerson {
@Column(name = "ROLE")
privateString role;
@Id
private Project project;
@Id
private Person person;
publicstatic class PK implements Serializable {
@ManyToOne(cascade = CascadeType.ALL)
@JoinColumn(name="PROJECT_ID")
private Project project;
@ManyToOne(cascade = CascadeType.ALL)
@JoinColumn(name="PERSON_ID")
private Person person;
@Override
publicboolean equals(Object o) {
if (this == o) returntrue;
if (o == null || getClass() != o.getClass()) returnfalse;
PK pk = (PK) o;
if (person != null ? !person.equals(pk.person) : pk.person != null) returnfalse;
if (project != null ? !project.equals(pk.project) : pk.project != null) returnfalse;
returntrue;
}
@Override
publicint hashCode() {
int result = project != null ? project.hashCode() : 0;
result = 31 * result + (person != null ? person.hashCode() : 0);
return result;
}
}
publicString getRole() {
return role;
}
public void setRole(String role) {
this.role = role;
}
public Project getProject() {
return project;
}
public void setProject(Project project) {
this.project = project;
}
public Person getPerson() {
return person;
}
public void setPerson(Person person) {
this.person = person;
}
@Override
publicboolean equals(Object o) {
if (this == o) returntrue;
if (o == null || getClass() != o.getClass()) returnfalse;
ProjectXPerson that = (ProjectXPerson) o;
if (person != null ? !person.equals(that.person) : that.person != null) returnfalse;
if (project != null ? !project.equals(that.project) : that.project != null) returnfalse;
returntrue;
}
@Override
publicint hashCode() {
int result = project != null ? project.hashCode() : 0;
result = 31 * result + (person != null ? person.hashCode() : 0);
return result;
}
}
My test case:
MTMTest.java
package com.tnf.db.ass.mtm;
import com.tnf.db.persistence.util.PersistenceUtil;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.context.transaction.TransactionConfiguration;
import org.springframework.transaction.annotation.Transactional;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = { "classpath:/beans-test.xml" })
@TransactionConfiguration(transactionManager = "transactionManager", defaultRollback = true)
@Transactional
public class MTMTest {
@PersistenceContext(unitName = PersistenceUtil.PERSISTENCE_UNIT_NAME)
protected EntityManager em;
@Test
public void create() throws Exception {
Person joe = new Person();
joe.setName("Joe");
//em.persist(joe);
Person jane = new Person();
jane.setName("Jane");
//em.persist(jane);
Project manhattan = new Project();
manhattan.setName("Manhattan");
em.persist(manhattan);
manhattan.addPerson(joe, "Engineer");
manhattan.addPerson(jane, "Engineer");
em.flush();
em.clear();
}
}
This test case fails with following exception:
java.lang.NullPointerException
at org.hibernate.type.AbstractType.getHashCode(AbstractType.java:136)
at org.hibernate.type.AbstractType.getHashCode(AbstractType.java:144)
at org.hibernate.type.EntityType.getHashCode(EntityType.java:312)
at org.hibernate.type.ComponentType.getHashCode(ComponentType.java:212)
at org.hibernate.engine.EntityKey.generateHashCode(EntityKey.java:126)
at org.hibernate.engine.EntityKey.<init>(EntityKey.java:70)
at org.hibernate.event.def.AbstractSaveEventListener.performSave(AbstractSaveEventListener.java:184)
at org.hibernate.event.def.AbstractSaveEventListener.saveWithGeneratedId(AbstractSaveEventListener.java:144)
at org.hibernate.ejb.event.EJB3PersistEventListener.saveWithGeneratedId(EJB3PersistEventListener.java:49)
at org.hibernate.event.def.DefaultPersistEventListener.entityIsTransient(DefaultPersistEventListener.java:154)
at org.hibernate.event.def.DefaultPersistEventListener.onPersist(DefaultPersistEventListener.java:110)
at org.hibernate.impl.SessionImpl.firePersistOnFlush(SessionImpl.java:671)
at org.hibernate.impl.SessionImpl.persistOnFlush(SessionImpl.java:663)
at org.hibernate.engine.CascadingAction$9.cascade(CascadingAction.java:346)
at org.hibernate.engine.Cascade.cascadeToOne(Cascade.java:291)
at org.hibernate.engine.Cascade.cascadeAssociation(Cascade.java:239)
at org.hibernate.engine.Cascade.cascadeProperty(Cascade.java:192)
at org.hibernate.engine.Cascade.cascadeCollectionElements(Cascade.java:319)
at org.hibernate.engine.Cascade.cascadeCollection(Cascade.java:265)
at org.hibernate.engine.Cascade.cascadeAssociation(Cascade.java:242)
at org.hibernate.engine.Cascade.cascadeProperty(Cascade.java:192)
at org.hibernate.engine.Cascade.cascade(Cascade.java:153)
at org.hibernate.event.def.AbstractFlushingEventListener.cascadeOnFlush(AbstractFlushingEventListener.java:154)
at org.hibernate.event.def.AbstractFlushingEventListener.prepareEntityFlushes(AbstractFlushingEventListener.java:145)
at org.hibernate.event.def.AbstractFlushingEventListener.flushEverythingToExecutions(AbstractFlushingEventListener.java:88)
at org.hibernate.event.def.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:49)
at org.hibernate.impl.SessionImpl.flush(SessionImpl.java:1027)
at org.hibernate.ejb.AbstractEntityManagerImpl.flush(AbstractEntityManagerImpl.java:304)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at org.springframework.orm.jpa.SharedEntityManagerCreator$SharedEntityManagerInvocationHandler.invoke(SharedEntityManagerCreator.java:240)
at $Proxy63.flush(Unknown Source)
at com.tnf.db.ass.mtm.MTMTest.create(MTMTest.java:43)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:44)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:41)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:20)
at org.springframework.test.context.junit4.statements.RunBeforeTestMethodCallbacks.evaluate(RunBeforeTestMethodCallbacks.java:74)
at org.springframework.test.context.junit4.statements.RunAfterTestMethodCallbacks.evaluate(RunAfterTestMethodCallbacks.java:82)
at org.springframework.test.context.junit4.statements.SpringRepeat.evaluate(SpringRepeat.java:72)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:240)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:50)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:193)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:52)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:191)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:42)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:184)
at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61)
at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:70)
at org.junit.runners.ParentRunner.run(ParentRunner.java:236)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:180)
at org.junit.runner.JUnitCore.run(JUnitCore.java:157)
at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:71)
at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:202)
at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:63)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:120)
If I remove comments from em.persist(joe); and em.persist(jane); lines it works as expected
I'm experiencing the same issue with Hibernate 3.3.1.GA (Part of JBoss 5.1.0.GA):
My test case:
This test case fails with following exception:
If I remove comments from em.persist(joe); and em.persist(jane); lines it works as expected