StackOverflow during merge of pair of detached entities in JBoss EAP
Environment
- Red Hat JBoss Enterprise Application Platform (EAP)
- 7.3
- 7.2
- Hibernate 5.3
Issue
-
A "many to many" association (e.g. between
EmployeeandTaskin the example below) is defined using an intermediate entity (e.g.TaskParticipantin the example below). -
The intermediate entity uses an {{@Embeddable}} (primary) key that maps a
ManyToOne}association with both classes. -
During merge of a detached entity on one side of the association (e.g.
Employee), a non-terminating, recursive load loop is initiated resulting in an eventualjava.lang.StackOverflowError. -
The repeating portion of the stack is shown below:
... java.lang.StackOverflowError ... at org.hibernate.internal.SessionImpl.fireLoadNoChecks(SessionImpl.java:1277) at org.hibernate.internal.SessionImpl.immediateLoad(SessionImpl.java:1119) at org.hibernate.proxy.AbstractLazyInitializer.initialize(AbstractLazyInitializer.java:178) at org.hibernate.proxy.AbstractLazyInitializer.getIdentifier(AbstractLazyInitializer.java:89) at org.hibernate.type.EntityType.getHashCode(EntityType.java:372) at org.hibernate.type.ComponentType.getHashCode(ComponentType.java:242) at org.hibernate.engine.spi.EntityKey.generateHashCode(EntityKey.java:61) at org.hibernate.engine.spi.EntityKey.<init>(EntityKey.java:54) at org.hibernate.internal.AbstractSharedSessionContract.generateEntityKey(AbstractSharedSessionContract.java:524) at org.hibernate.loader.Loader.extractKeysFromResultSet(Loader.java:879) at org.hibernate.loader.Loader.getRowFromResultSet(Loader.java:729) at org.hibernate.loader.Loader.processResultSet(Loader.java:1002) at org.hibernate.loader.Loader.doQuery(Loader.java:960) at org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:351) at org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:321) at org.hibernate.loader.Loader.loadEntity(Loader.java:2379) at org.hibernate.loader.entity.AbstractEntityLoader.load(AbstractEntityLoader.java:64) at org.hibernate.loader.entity.AbstractEntityLoader.load(AbstractEntityLoader.java:54) at org.hibernate.persister.entity.AbstractEntityPersister.load(AbstractEntityPersister.java:4289) at org.hibernate.event.internal.DefaultLoadEventListener.loadFromDatasource(DefaultLoadEventListener.java:597) at org.hibernate.event.internal.DefaultLoadEventListener.doLoad(DefaultLoadEventListener.java:565) at org.hibernate.event.internal.DefaultLoadEventListener.load(DefaultLoadEventListener.java:226) at org.hibernate.event.internal.DefaultLoadEventListener.doOnLoad(DefaultLoadEventListener.java:122) at org.hibernate.event.internal.DefaultLoadEventListener.onLoad(DefaultLoadEventListener.java:93) ...
Source Code Example/Excerpt
@Entity
public class Employee {
@Id
private String name;
@OneToMany(mappedBy = "taskParticipantPK.employee", cascade = CascadeType.ALL, orphanRemoval = true)
private List<TaskParticipant> taskParticipants;
}
@Entity
public class Task {
@Id
private long id;
@OneToMany(mappedBy = "taskParticipantPK.task", cascade=CascadeType.ALL)
private List <TaskParticipant> taskParticipants;
}
@Entity
public class TaskParticipant {
@EmbeddedId
private TaskParticipantPK taskParticipantPK = new TaskParticipantPK();
}
@Embeddable
@Table(name = "TaskParticipant")
public class TaskParticipantPK implements Serializable {
private static final long serialVersionUID = 1;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "employee")
private Employee employee;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "task")
private Task task;
}
Resolution
This issue will be addressed in a future release1.
In older release versions, it may be possible to set Content from docs.jboss.org is not included.hibernate.jpa.compliance.proxy to false to work around the issue.
<property name="hibernate.jpa.compliance.proxy" value="false"/>
Root Cause
This is a known defect (Content from hibernate.atlassian.net is not included.HHH-14608).
This solution is part of Red Hat’s fast-track publication program, providing a huge library of solutions that Red Hat engineers have created while supporting our customers. To give you the knowledge you need the instant it becomes available, these articles may be presented in a raw and unedited form.