Hi all,
RequestFactory seems to fetch whatever the collection I have in my ValueProxy eagarly.
Lets see the code
@Entity
public class Venue implements Serializable {
private name;
private Address address;
....
private Set<VenueContact> contacts;
@OneToMany(fetch = FetchType.LAZY)
public Set<VenueContact> getVenueContactses() {
return this.contacts;
}
//.... other getters and setters
}
Lets assume I have set everything else for RequestFactory and Hibernate (Hibernate standalone tests run fine) in order.
I call the below code from client:
requestFactory.venueRequest.findById(7).fire(new Reciever<VenueProxy>() {
public void onSuccess(VenueProxy res) {
}
});
In service method
public Venue findById() {
//currently I am using a command pattern for a unit of transaction but anyway I just write simply whats happening
// assume try catch and variable declaration code
session = HibernateUtil.getSessionFactory.openSession();
trx = session.getTrasaction();
trx.beginTransaction();
venue = veneuDao.findById(7);
trx.commit();
session.close();
}
##############################################################################################
Run Application and get this exception
org.hibernate.LazyInitializationException: failed to lazily initialize a collection of role: com.xxxxx.xxxx.dto.Venue.contacts, no session or session was closed
at org.hibernate.collection.AbstractPersistentCollection.throwLazyInitializationException(AbstractPersistentCollection.java:383)
at org.hibernate.collection.AbstractPersistentCollection.throwLazyInitializationExceptionIfNotConnected(AbstractPersistentCollection.java:375)
at org.hibernate.collection.AbstractPersistentCollection.initialize(AbstractPersistentCollection.java:368)
at org.hibernate.collection.AbstractPersistentCollection.read(AbstractPersistentCollection.java:111)
at org.hibernate.collection.PersistentSet.iterator(PersistentSet.java:186)
at com.google.web.bindery.requestfactory.server.Resolver.resolveClientValue(Resolver.java:617)
at com.google.web.bindery.requestfactory.server.Resolver.access$400(Resolver.java:50)
at com.google.web.bindery.requestfactory.server.Resolver$PropertyResolver.visitReferenceProperty(Resolver.java:139)
at com.google.web.bindery.autobean.shared.AutoBeanVisitor.visitCollectionProperty(AutoBeanVisitor.java:229)
at com.google.web.bindery.autobean.vm.impl.ProxyAutoBean.traverseProperties(ProxyAutoBean.java:300)
at com.google.web.bindery.autobean.shared.impl.AbstractAutoBean.traverse(AbstractAutoBean.java:166)
at com.google.web.bindery.autobean.shared.impl.AbstractAutoBean.accept(AbstractAutoBean.java:101)
at com.google.web.bindery.requestfactory.server.Resolver.resolveClientValue(Resolver.java:395)
at com.google.web.bindery.requestfactory.server.SimpleRequestProcessor.processInvocationMessages(SimpleRequestProcessor.java:483)
at com.google.web.bindery.requestfactory.server.SimpleRequestProcessor.process(SimpleRequestProcessor.java:225)
at com.google.web.bindery.requestfactory.server.SimpleRequestProcessor.process(SimpleRequestProcessor.java:127)
at com.google.web.bindery.requestfactory.server.RequestFactoryServlet.doPost(RequestFactoryServlet.java:133)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:637)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
at org.mortbay.jetty.servlet.ServletHolder.handle(ServletHolder.java:487)
at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1097)
at com.xxxxx.xxxxx.xxxxx.PersistenceFilter.doFilter(PersistenceFilter.java:35)
at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1088)
at org.mortbay.jetty.servlet.ServletHandler.handle(ServletHandler.java:360)
at org.mortbay.jetty.security.SecurityHandler.handle(SecurityHandler.java:216)
at org.mortbay.jetty.servlet.SessionHandler.handle(SessionHandler.java:181)
at org.mortbay.jetty.handler.ContextHandler.handle(ContextHandler.java:729)
at org.mortbay.jetty.webapp.WebAppContext.handle(WebAppContext.java:405)
at org.mortbay.jetty.handler.HandlerWrapper.handle(HandlerWrapper.java:152)
at org.mortbay.jetty.handler.RequestLogHandler.handle(RequestLogHandler.java:49)
at org.mortbay.jetty.handler.HandlerWrapper.handle(HandlerWrapper.java:152)
at org.mortbay.jetty.Server.handle(Server.java:324)
at org.mortbay.jetty.HttpConnection.handleRequest(HttpConnection.java:505)
at org.mortbay.jetty.HttpConnection$RequestHandler.content(HttpConnection.java:843)
at org.mortbay.jetty.HttpParser.parseNext(HttpParser.java:647)
at org.mortbay.jetty.HttpParser.parseAvailable(HttpParser.java:211)
at org.mortbay.jetty.HttpConnection.handle(HttpConnection.java:380)
at org.mortbay.io.nio.SelectChannelEndPoint.run(SelectChannelEndPoint.java:395)
at org.mortbay.thread.QueuedThreadPool$PoolThread.run(QueuedThreadPool.java:488)
###################################################################################################
But when I run the same kind of transaction under a test or under 'public static void main(..' it does well.
Also I might have noticed somewhere in RequestFactory API we try to invoke all methods having collections, somewhere in highlighted text exceptions
As I have read the RequestFactory doc :
"When querying the server, RequestFactory does not automatically populate relations in the object graph. To do this, use the with() method on a request and specify the related property name as a String:".
I was expecting that the rule will also apply to Collections of related proxy.
Do I have to make a choice 1) have only eagarly fetch collection in proxy or 2) do not have any ?
I expect one suggestion may come out here to have a filter that maintains one transaction and session per request. But would it be good practice to have transaction per request.
In the end being too tired, I am just putting my question as short as possible. I am sorry if it doesn't appear very clear, in that case I can reply back to any quries.
Thanks in advance