Would like to hear experts on best practice of editing JPA entities from JSF UI.
So, a couple of words about the problem.
Imagine I have the persisted object MyEntity
and I fetch it for editing. In DAO layer I use
return em.find(MyEntity.class, id);
Which returns MyEntity
instance with proxies on "parent" entities - imagine one of them is MyParent
. MyParent
is fetched as the proxy greeting to @Access(AccessType.PROPERTY)
:
@Entity
public class MyParent {
@Id
@Access(AccessType.PROPERTY)
private Long id;
//...
}
and MyEntity has the reference to it:
@ManyToOne(fetch = FetchType.LAZY)
@LazyToOne(LazyToOneOption.PROXY)
private MyParent myParent;
So far so good. In UI I simply use the fetched object directly without any value objects created and use the parent object in the select list:
<h:selectOneMenu value="#{myEntity.myParent.id}" id="office">
<f:selectItems value="#{parents}"/>
</h:selectOneMenu>
Everything is rendered ok, no LazyInitializationException
occurs. But when I save the object I recieve the
LazyInitializationException: could not initialize proxy - no Session
on MyParent
proxy setId()
method.
I can easily fix the problem if I change the MyParent
relation to EAGER
@ManyToOne(fetch = FetchType.EAGER)
private MyParent myParent;
or fetch the object using left join fetch p.myParent
(actually that's how I do now). In this case the save operation works ok and the relation is changed to the new MyParent
object transparently. No additional actions (manual copies, manual references settings) need to be done. Very simple and convenient.
BUT. If the object references 10 other object - the em.find()
will result 10 additional joins, which isn't a good db operation, especially when I don't use references objects state at all. All I need - is links to objects, not their state.
This is a global issue, I would like to know, how JSF specialists deal with JPA entities in their applications, which is the best strategy to avoid both extra joins and LazyInitializationException
.
Extended persistence context isn't ok for me.
Thanks!