Hibernation / Spring 3: proxy cannot be initialized - no session

I'm new to Spring, so I put Spring 3.0M3 on a Tomcat server on my Mac, made an Eclipse project, completed Hello World, and then wanted to make an object with Hibernate. I created a User table on my MySQL server, created a User object with all the getters and setters (I really want Java to queue from Objective-C here and add dynamic properties. Too much mess of code with the generated property code), created a UserDao object for search and save the user and created the bean configuration. This is going well ... except that the session is not initialized. Why is this? I can access the database just fine from this computer using these credentials.

I understand that this is probably just a normal newbie, but all I found was a mistake, while googling are people who lose sessions in the middle when switching from Hibernate 2 to 3. I donโ€™t switch, and as far as I can judge the session was never done.

Here is my mistake:

SEVERE: Servlet.service() for servlet HelloApp threw exception org.hibernate.LazyInitializationException: could not initialize proxy - no Session at org.hibernate.proxy.AbstractLazyInitializer.initialize(AbstractLazyInitializer.java:57) at org.hibernate.proxy.AbstractLazyInitializer.getImplementation(AbstractLazyInitializer.java:111) at org.hibernate.proxy.pojo.cglib.CGLIBLazyInitializer.invoke(CGLIBLazyInitializer.java:150) at com.saers.data.entities.User$$EnhancerByCGLIB$$c2f16afd.getName(<generated>) at com.saers.view.web.controller.HelloWorldController.handleRequestInternal(HelloWorldController.java:22) at org.springframework.web.servlet.mvc.AbstractController.handleRequest(AbstractController.java:153) at org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter.handle(SimpleControllerHandlerAdapter.java:48) at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:763) at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:709) at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:613) at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:525) at javax.servlet.http.HttpServlet.service(HttpServlet.java:617) at javax.servlet.http.HttpServlet.service(HttpServlet.java:717) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206) at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:233) at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:191) at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:128) at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102) at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109) at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:293) at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:849) at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:583) at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:454) at java.lang.Thread.run(Thread.java:637) 

Here is my servlet configurator for related beans:

 <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"> <property name="driverClassName" value="com.mysql.jdbc.Driver" /> <property name="url" value="jdbc:mysql://10.0.0.3:3306/HelloDB" /> <property name="username" value="hello" /> <property name="password" value="w0rld" /> <property name="initialSize" value="2" /> <property name="maxActive" value="5" /> </bean> <bean id="sessionFactory" class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean"> <property name="dataSource" ref="dataSource"/> <property name="annotatedClasses"> <list> <value>com.saers.data.entities.User</value> </list> </property> <property name="hibernateProperties"> <props> <prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop> <prop key="hibernate.show_sql">true</prop> <prop key="hibernate.lazy">false</prop> </props> </property> </bean> <bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager"> <property name="sessionFactory" ref="sessionFactory"/> </bean> <bean id="userDAO" class="com.saers.data.dao.UserDao"> <property name="sessionFactory" ref="sessionFactory"/> </bean> <bean id="txProxyTemplate" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean" abstract="true"> <property name="transactionManager" ref="transactionManager"/> <property name="transactionAttributes"> <props> <prop key="add*">PROPAGATION_REQUIRED</prop> <prop key="update*">PROPAGATION_REQUIRED</prop> <prop key="delete*">PROPAGATION_REQUIRED</prop> <prop key="*">PROPAGATION_SUPPORTS,readOnly</prop> </props> </property> </bean> <bean id="userService" parent="txProxyTemplate"> <property name="target"> <bean class="com.saers.business.UserServiceImpl"> <property name="userDao" ref="userDAO"/> </bean> </property> <property name="proxyInterfaces" value="com.saers.business.UserService"/> </bean> <bean name="/" class="com.saers.view.web.controller.HelloWorldController"> <property name="userService" ref="userService"/> </bean> 

Here is my user class:

 package com.saers.data.entities; import java.util.Date; import java.io.Serializable; import javax.persistence.*; @Entity @Table(name = "User") public class User implements Serializable { private static final long serialVersionUID = -6123654414341191669L; @Id @Column(name = "WebUserId") private String WebUserId; @Column(name = "Name") private String Name; /** * @return the webUserId */ public synchronized String getWebUserId() { return WebUserId; } /** * @param webUserId the webUserId to set */ public synchronized void setWebUserId(String webUserId) { WebUserId = webUserId; } /** * @return the name */ public synchronized String getName() { return Name; } /** * @param name the name to set */ public synchronized void setName(String name) { Name = name; } } 

And here is my UserDao:

 package com.saers.data.dao; import java.util.List; import com.saers.data.entities.User; import org.springframework.orm.hibernate3.support.*; public class UserDao extends HibernateDaoSupport { public void saveUser(User user) { getHibernateTemplate().saveOrUpdate(user); } public User lookupUser(String WebUserId) { User user = getHibernateTemplate().load(User.class, WebUserId); return user; return user; } } 

Here is my UserService interface

 public interface UserService { public User lookupUser(String webUserId); public void setUserDao(UserDao userDao); } 

and its implementation:

 public class UserServiceImpl implements UserService { private UserDao userDao; public void setUserDao(UserDao userDao) { this.userDao = userDao; } @Override public User lookupUser(String webUserId) { return userDao.lookupUser(webUserId); } } 

And finally, here is my HelloWorldController:

 package com.saers.view.web.controller; import com.saers.data.entities.User; import com.saers.business.UserService; import org.springframework.web.servlet.mvc.*; import org.springframework.web.servlet.*; import javax.servlet.http.*; import org.apache.commons.logging.*; public class HelloWorldController extends AbstractController { protected final Log logger = LogFactory.getLog(getClass()); @Override public ModelAndView handleRequestInternal(HttpServletRequest request, HttpServletResponse response) throws Exception { logger.info("Get bean"); User user = userService.lookupUser("helloUser"); logger.info("Found out that this user was last changed " + user.getName()); logger.info("Return View"); ModelAndView mv = new ModelAndView("HelloWorld.jsp", "user", user); return mv; } private UserService userService = null; public void setUserService(UserService userService) { this.userService = userService; } } 

I hope you have some useful tips that I can use :-) If there is anything else in the code, you feel like I'm doing the wrong / non-w762> way, I would also like to hear about it.

Greetings

 Nik 
+4
source share
2 answers

The stack trace does not match the sample code you sent for UserDao . The trace says that you call HibernateTemplate.initialize() from UserDao.lookupUser() , but your sample code does not do such a thing (as it should not, initialize() should not be called here).

Edit: OK, with the new stack trace, the problem seems to be that you are calling hibernateTemplate.load() , which should only be used in certain circumstances (and this is not one of them). You should probably call hibernateTemplate.get() .

+8
source

When you make a dao call, you "load" the object. The download does not get into the database, it returns the proxy server to the object so that the database crashes only if necessary.

You did not start the transaction before downloading - loading works because you do not have transaction readings enabled (by default it is enabled). He does not say, sorry, no transaction (this basically creates one for you to read, which ends immediately).

Thus, when you make getName, when it really gets into the database, it tells you โ€œno sessionโ€ because the session that loaded this object was closed (it was immediately closed).

What you need to do to fix this, start the transaction at the beginning of the servlet call and end it at the end - this way, when you make getName, the session will still be available.

Perhaps there is something in spring that will handle this plumbing for you.

+3
source

All Articles