Win a copy of The Java Performance Companion this week in the Performance forum!
  • Post Reply
  • Bookmark Topic Watch Topic
  • New Topic

Hibernate error with Spring MVC

 
K. Tsang
Bartender
Posts: 3457
14
Android Java
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hello all I'm new to Spring MVC and have a registration form. When I submit I got "org.hibernate.HibernateException: No Hibernate Session bound to thread, and configuration does not allow creation of non-transactional one here"

WEB-INF/applicationContext.xml


WEB-INF/dispatcher-servlet.xml


When I run the form, it first like this RegisterUserController -> UserServiceImpl -> UserDaoImpl. I noticed from my server log that the problem should be in UserDaoImpl - not able to get the current session from hibernate's session factory. My UserDaoImpl looks like:


The server log is:
hibernate session factory null?false
getting hibernate session
StandardWrapperValve[dispatcher]: PWC1406: Servlet.service() for servlet dispatcher threw exception
org.hibernate.HibernateException: No Hibernate Session bound to thread, and configuration does not allow creation of non-transactional one here


Is this a config or coding problem? How can I get this to work? Thanks.
 
Mark Spritzler
ranger
Sheriff
Posts: 17278
6
IntelliJ IDE Mac Spring
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Your Service layer is where you set your transactional boundaries

So you need to mark UserServiceImpl as transactional. If you use annotations you can either put @Transactional on the class or a particular public method, then in your xml use the <tx:annotation-config> configuration to let Spring know to go look for that annotation. (tag might have mispelling as I don't have tags memorized)

Or in xml you can use aop to set a the method as transactional.

Both you can find in the documentation of SpringSource under transactions section

Good Luck

Mark
 
K. Tsang
Bartender
Posts: 3457
14
Android Java
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Thanks Mark, you were right, I need to set transactional stuff in my service class. I added the following to my service class:

Then in my applicationContext.xml file I added property:
<property name="txManager" ref="transactionManager" />
to the userService bean then add
<tx:annotation-driven />

Now everything works fine. Oh while I'm at it, when my registration form submits sucessfully, it currently goes back to the form, how can I set it to go to some other page like a success page? Do I set this in the xml file (dispatcher-servlet or applicationContext)? Or some other place like in my controller class.

Thanks.
 
Mark Spritzler
ranger
Sheriff
Posts: 17278
6
IntelliJ IDE Mac Spring
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Actually you don't need to have
<property name="txManager" ref="transactionManager" />
or that property in your service class.

For going to a different page, you can have the Controller method do a redirect. It is usually nice to do a post, then redirect to a get. That is the RESTful way of doing things. You can have your controller method return a different String for the view to have the viewResolver go to a different page.

Basically, it is all about what gets returned as the "view" from your Controller method.

Mark
 
K. Tsang
Bartender
Posts: 3457
14
Android Java
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Thanks for your quick response Mark. Ok I got everything in order Ok got some more questions:

Since I used Hibernate, and my hibernate settings are in WEB-INF/applicationContext.xml file, do I really need that hibernate-cfg.xml file that practically comes with Hibernate?

Now for that transaction thing <tx:annotation-driven /> ... suppose I now want to run it under J2EE1.4 and since 1.4 does not support annotations, how to use <tx:advice> and aop to get around this? If the xml config is fine, do I need to cater my service class to explicitly start transaction blablabla? Currently I have

Since my aop pointcut uses AspectJ syntax, I download AspectJ jars and I left my service class unchanged (just remove the @Transactional annotations), everything works again

Not sure if you know AspectJ much. If I did not use AspectJ syntax, what's the pointcut should look like? Is it just regexp for what my service (here UserService)? Do I need to add multiple aop:advisor for each service or is that a wildcard for all my services?

Apart from using the above approach, is there another approach to achieve the same goal as the annotated transaction version (<tx:annotation-driven/>)?

Thanks again.
 
Mark Spritzler
ranger
Sheriff
Posts: 17278
6
IntelliJ IDE Mac Spring
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
"Since I used Hibernate, and my hibernate settings are in WEB-INF/applicationContext.xml file, do I really need that hibernate-cfg.xml file that practically comes with Hibernate? "

No you do not need the hibernate.cfg.xml, unless you are no longer using Spring.

Also, sometimes you might use it with your ide to use the Hibernate plugins for either IntelliJ or Eclipse.

Normally you would actually put the Spring configuration for data access stuff into a different file than the applicationContext, so that you break that xml into multiple files and each file for a particular purpose. Like dataAccess.xml or applicationContext-security.xml

the AOP and @Transactional is specifically Spring, maybe someday @Transactional with be a part of the javax.annotations JSR.

Mark
 
  • Post Reply
  • Bookmark Topic Watch Topic
  • New Topic