I am new to Hibernate and am running into an issue that seems pretty common, when I search on it, but haven't found a solution. I am using Seam 2.2.1, Hibernate 3 and JSF.
I have an entity: Request, which has a requester:
Code:
@ManyToOne(fetch=FetchType.EAGER, cascade={CascadeType.MERGE,CascadeType.REFRESH})
@JoinColumn(name="requester_badge", referencedColumnName="badge_number")
private PersonSnapshotEntity requester;
and has zero or more approvals:
Code:
@OneToMany(mappedBy = "request", cascade={CascadeType.ALL})
@Cache(usage = CacheConcurrencyStrategy.READ_WRITE)
private List<ApprovalEntity> approvals;
and zero or one type:
Code:
@ManyToOne(fetch=FetchType.EAGER, cascade={CascadeType.MERGE})
@JoinColumn(name="publication_type", referencedColumnName="id")
private PublicationTypeEntity publicationType;
among other relationships.
My Approval entity has an approver (PersonSnapshotEntity, also):
Code:
@NotNull
@ManyToOne(fetch=FetchType.EAGER, cascade={CascadeType.MERGE,CascadeType.REFRESH})
@JoinColumn(name="approver_badge", referencedColumnName="badge_number")
private PersonSnapshotEntity approver;
So, my relationships are all unidirectional.
I understand that I cannot eagerly fetch all of the child collections (approvals, notes, notifications...) due to a limitation in Hibernate.
When I first submit a Request, providing a requester, a type, a description and an approval, I am able to submit it the first time through without any exceptions. However, if I attempt to submit a change to it, I get the dreaded "detached entity" error. Based on the stack trace, it
appears to be related to the assignment of the approver to the approval. As I step into my breakpoint, I see the PersonSnapshotEntity being referenced is that of a manager who is named in the approval in the test. This is the exception:
Code:
Caused by: org.hibernate.PersistentObjectException: detached entity passed to persist: org.aero.libreq.entity.PersonSnapshotEntity
When I go to save the request and the child approval is persisted, logic tries to pull a fresh copy of the personSnapshot by the id from the database before the persist. But the ID comes back null.
How can I assure that these objects are correctly synchronized when I pull them from the database, when I update them in the UI (user can change the approver in an approval, for example) and when I persist/merge the changes?
Thanks!
Ginni