]
Muammer Yucel commented on HHH-3441:
------------------------------------
I encountered to this problem and after debug I saw that hibernate tries to calculate
hascode with IDs of other persistent entities. Since they are transient at the moment and
ids are not generated, NPE is thrown. Why does hibernate use IDs instead of using
Object's hashCode() method to get hash code of the entity?
Null pointer exception on
org.hibernate.type.AbstractType.getHashCode(AbstractType.java:112)
--------------------------------------------------------------------------------------------
Key: HHH-3441
URL:
http://opensource.atlassian.com/projects/hibernate/browse/HHH-3441
Project: Hibernate Core
Issue Type: Bug
Components: core
Affects Versions: 3.2.5
Environment: Hibernate 3.25., Oracle 10g, Spring 2.5.5
Reporter: DEROUET
Priority: Blocker
The issue concerns a problem already signaled in different forums, and I decided to
report it in JIRA, because many people have this same problem and after days and days of
work around, the solutions possibles are heavy or dangerous for a database integrity (for
example remove a non-nullability constraint...).
Here it is the problem a previous forum participant had perfectly summarized (see
http://opensource.atlassian.com/projects/hibernate/browse/HHH-2326):
A null pointer exception is thrown when:
a) we have a composite key with one of the attributes of the key being an FK to another
persistent class.
b) The other persistent class has an ID field whose value is being generated.
c) The instance of the other persistent class is transient (does not yet have an ID)
We do not get the null pointer if we explicitly set the ID (generator=assigned)
Here it is the failure trace:
-->
-->
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.engine.StatefulPersistenceContext.getDatabaseSnapshot(StatefulPersistenceContext.java:240)
at org.hibernate.engine.ForeignKeys.isTransient(ForeignKeys.java:189)
at
org.hibernate.event.def.AbstractSaveEventListener.getEntityState(AbstractSaveEventListener.java:512)
at
org.hibernate.event.def.DefaultSaveOrUpdateEventListener.performSaveOrUpdate(DefaultSaveOrUpdateEventListener.java:80)
at
org.hibernate.event.def.DefaultSaveOrUpdateEventListener.onSaveOrUpdate(DefaultSaveOrUpdateEventListener.java:70)
at org.hibernate.impl.SessionImpl.fireSaveOrUpdate(SessionImpl.java:507)
at org.hibernate.impl.SessionImpl.saveOrUpdate(SessionImpl.java:499)
at org.hibernate.impl.SessionImpl.saveOrUpdate(SessionImpl.java:495)
at
org.springframework.orm.hibernate3.HibernateTemplate$16.doInHibernate(HibernateTemplate.java:747)
at
org.springframework.orm.hibernate3.HibernateTemplate.doExecute(HibernateTemplate.java:419)
at
org.springframework.orm.hibernate3.HibernateTemplate.executeWithNativeSession(HibernateTemplate.java:374)
at
org.springframework.orm.hibernate3.HibernateTemplate.saveOrUpdate(HibernateTemplate.java:744)
at
eu.cec.argus.bcm.dao.businessContinuityEvent.BusinessContinuityEventDAOImpl.createBCEvent(BusinessContinuityEventDAOImpl.java:39)
at
eu.cec.argus.bcm.dao.businessContinuityEvent.BusinessContinuityEventDAOTest.testSaveBcEventAndRelatedMessagesAndMeetings(BusinessContinuityEventDAOTest.java:127)
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.lang.reflect.Method.invoke(Method.java:585)
at
org.springframework.test.context.junit4.SpringTestMethod.invoke(SpringTestMethod.java:198)
at
org.springframework.test.context.junit4.SpringMethodRoadie.runTestMethod(SpringMethodRoadie.java:274)
at
org.springframework.test.context.junit4.SpringMethodRoadie$2.run(SpringMethodRoadie.java:207)
at
org.springframework.test.context.junit4.SpringMethodRoadie.runBeforesThenTestThenAfters(SpringMethodRoadie.java:254)
at
org.springframework.test.context.junit4.SpringMethodRoadie.runWithRepetitions(SpringMethodRoadie.java:234)
at
org.springframework.test.context.junit4.SpringMethodRoadie.runTest(SpringMethodRoadie.java:204)
at
org.springframework.test.context.junit4.SpringMethodRoadie.run(SpringMethodRoadie.java:146)
at
org.springframework.test.context.junit4.SpringJUnit4ClassRunner.invokeTestMethod(SpringJUnit4ClassRunner.java:151)
at org.junit.internal.runners.JUnit4ClassRunner.runMethods(JUnit4ClassRunner.java:51)
at org.junit.internal.runners.JUnit4ClassRunner$1.run(JUnit4ClassRunner.java:44)
at org.junit.internal.runners.ClassRoadie.runUnprotected(ClassRoadie.java:26)
at org.junit.internal.runners.ClassRoadie.runProtected(ClassRoadie.java:36)
at org.junit.internal.runners.JUnit4ClassRunner.run(JUnit4ClassRunner.java:42)
at
org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:38)
at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
at
org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:460)
at
org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:673)
at
org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:386)
at
org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:196)
Here they are my classes:
@Entity
@Table(name = "BCM_BC_EVENT")
@IdClass(BusinessContinuityEvent.BusinessContinuityEventId.class)
@SequenceGenerator(name = "Generator.BusinessContinuityEvent", sequenceName =
"SEQ_BCM_BC_EVENT")
public class BusinessContinuityEvent implements Serializable {
@Embeddable
public static class BusinessContinuityEventId implements Serializable {
private static final long serialVersionUID = 3513299649110908676L;
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator =
"Generator.BusinessContinuityEvent")
@Column(name = "BCE_ID", insertable = false, updatable = false,
nullable = false)
private Long id;
@ManyToOne(fetch = FetchType.LAZY, cascade = {CascadeType.PERSIST,
CascadeType.REFRESH, CascadeType.MERGE})
@Cascade(org.hibernate.annotations.CascadeType.SAVE_UPDATE)
@JoinColumn(name = "EVE_ID", referencedColumnName = "EVE_ID",
nullable = false)
private Event event;
public BusinessContinuityEventId(){
}
public BusinessContinuityEventId(Long id, Event event) {
this.id = id;
this.event = event;
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public Event getEvent() {
return event;
}
public void setEvent(Event event) {
this.event = event;
}
@Override
public boolean equals(Object obj) {
if (obj instanceof BusinessContinuityEventId) {
BusinessContinuityEventId other = (BusinessContinuityEventId) obj;
return this.event.getId().equals(other.event.getId())
&& this.id.equals(other.id);
}
return false;
}
@Override
public int hashCode() {
return this.event.getId().hashCode() ^ this.id.hashCode();
}
}
private static final long serialVersionUID = 5385009048448590115L;
@Id
private Long id;
@Id
private Event event;
@OneToMany(fetch = FetchType.LAZY, cascade = {CascadeType.PERSIST,
CascadeType.REFRESH, CascadeType.MERGE})
@Cascade(org.hibernate.annotations.CascadeType.SAVE_UPDATE)
@JoinColumns({
@JoinColumn(name = "BCE_ID", referencedColumnName =
"BCE_ID"),
@JoinColumn(name = "EVE_ID", referencedColumnName =
"EVE_ID")})
private List<Message> messages;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public Event getEvent() {
return event;
}
public void setEvent(Event event) {
this.event = event;
}
public List<Message> getMessages() {
return messages;
}
public void setMessages(List<Message> messages) {
this.messages = messages;
}
}
--
This message is automatically generated by JIRA.
-
If you think it was sent incorrectly contact one of the administrators: