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#4022862
Reply to the post :
http://www.jboss.com/index.html?module=bb&op=posting&mode=reply&p=4022862
_______________________________________________
jboss-user mailing list
[email protected]
https://lists.jboss.org/mailman/listinfo/jboss-user