Understanding JPA lazy loading
Using Glassfish 3.1 with Eclipselink as JPA provider on board. Got stateless bean with following code and Folder class wich is mapped to table. Each folder can have it's parent folder.
Stateless bean got following code.
@TransactionAttribute(TransactionAttributeType.REQUIRED)
public List<Folders> getUserFolders() {
return folderDao.findFolders();
}
And entity class
public class Folder {
@ManyToOne(fetch=FetchType.LAZY)
private Folder parent;
@OneToMany(targetEntity=Folder.class, mappedBy="parent", fetch=FetchType.LAZY)
private List<Folder> childFolders;
}
Consider following situation, Servlet invoke this bean to get all folders and iterate in cycle over the folder invoking getChildFolders() method.
FINEST: Connection acquired from connection pool [read].
FINEST: reconnecting to external connection pool
FINE: SELECT ID, FOLDERNAME, POSITION, OWNER_ID, PARENT_ID FROM t_user_folder WHERE (PARENT_ID = ?)
bind => [1 parameter bound]
FINEST: Connection released to connection pool [read].
Invocation of method getChildFolders() occurs outside of transactional method, persistent context is flushed already. And I can't开发者_Go百科 understand why LazyInitializationException does not throw and how container does know from where he should obtain connection. Can someone explain it please
Well, this situations arises from eclipselink architecture.. Eclipselink JPA implementation stil uses legacy Toplink session architecture.. There is one global server session, for non-transactional operations a new client-session is spawned from this server session, for transactional operations a UnitOfWork session is spawned.. In your case, there is no need for transaction, because it is just a read operation... But if you change your entity and call merge method , you would get Exception.. For more information, you can read this link
精彩评论