This is more a question of design or understanding:
In order to avoid the lazy initialization exception I have followed the seam examples and
used the TransactionalSeamPhaseListener and configured the components.xml correctly. The
entity manager is now injected using the @In annotation. I can now retrieve my entities
without problem however this raises an issue about JSF model updates which over-write the
primary key of a ManyToOne entity.
Example:
| EJB3:
| @Entity
| public class Person extends {
| private Title title;
|
| @ManyToOne(cascade = {}, fetch = FetchType.EAGER)
| @JoinColumn(name = "title_id", unique = false, nullable = true, insertable
= true, updatable = true)
| public Title getTitle() {
| return this.title;
| }
| .
| .
| }
|
| Backing Bean:
| @Stateful
| @Scope(ScopeType.CONVERSATION)
| @Name("editPerson")
| public class EditPerson {
| @In
| private EntityManager entityManager;
| @Out
| private Person person;
| .
| .
| }
|
| JSF:
| <h:selectOneMenu id="titleId"
value="#{person.title.titleId}"/>
|
The problem occurs when the title is changed in the selectOneMenu from say "Mr"
to "Mrs". JSF applies its model changes to person.title.titleId which changes
the primary key of the managed entity. Any calls to persist the person entity fail as two
title objects exist with the same primary key This seems to be a general problem for JSF
pages wanting to write directly to managed entities.
To avoid this problem I have reverted to the standard SeamPhaseListener and use the
@PersistenceContext. The entity is now "disconnected" and calls to merge() no
longer complain about the change in primary key they just perform the update. i.e update
person set titleId=2 . . .
This solution means that I have to initialise every lazy collection manually before
passing it to JSF.
A possible solution is to intercept the model update before it is applied and set the
title on person to the changed title:
| newTitleId = {Get model value for titleId}
| newTitle = em.find(Title.class, newTitleId)
| person.setTitle(newTitle)
| {Stop model update of person.title.titleId}
|
Another solution is have all selectOneMenus writing their value back to a property on the
backing bean instead of the entity. This however really curbs flexibility with reuse.
How should I do this? Is there a better way? Does anyone have a better design solution?
View the original post :
http://www.jboss.com/index.html?module=bb&op=viewtopic&p=4022862#...
Reply to the post :
http://www.jboss.com/index.html?module=bb&op=posting&mode=reply&a...