aspose file tools*
The moose likes Spring and the fly likes Trouble converting a Spring JDBC app to use Spring Hibernate Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login
JavaRanch » Java Forums » Frameworks » Spring
Bookmark "Trouble converting a Spring JDBC app to use Spring Hibernate" Watch "Trouble converting a Spring JDBC app to use Spring Hibernate" New topic
Author

Trouble converting a Spring JDBC app to use Spring Hibernate

Ray Clark
Ranch Hand

Joined: Aug 16, 2012
Posts: 52
Hi, I have a Spring application working with Spring JDBC and I'm trying to convert it to use Hibernate but I can't seem to get the Spring configuration right.

My application context file has the configuration for Hibernate connecting to a MySQL database. I want to use full annotations so my beans are not defined. Here is the config file:


Here is my data access class:



If I run the code like this I get the following error on the getCurrentSession() line:
No Hibernate Session bound to thread, and configuration does not allow creation of non-transactional one here

I've done much searching on the internet and trying various examples. I found suggestions adding the following property.
<prop key="hibernate.current_session_context_class">thread</prop>

When I do that I get the following error on the createQuery line:
createQuery is not valid without active transaction

Any suggestions as to what is wrong with my configuration?

Many Thanks,
Ray
Mark Spritzler
ranger
Sheriff

Joined: Feb 05, 2001
Posts: 17256
    
    6

No interface and therefore no transactions.

Transactions should belong set at the Use Case level so that Spring can better manage Connections, TransactionContext across a Use Case.

Anyway, I recommend creating an interface for your Repository and Service classes. Add @Transactional on your @Service classes and have your service class call the Repository.

However, you can still put @Transactional on your Repository, you just still need to create an interface for it and have your Repository implement it.

Also, I thought

<property name="packagesToScan" value="com.home.dvdtracker.domain" />

that property takes a List or an Array?

Thanks

Mark

Perfect World Programming, LLC - Two Laptop Bag - Tube Organizer
How to Ask Questions the Smart Way FAQ
Mark Spritzler
ranger
Sheriff

Joined: Feb 05, 2001
Posts: 17256
    
    6

I also recommend debugging your code through the debugger. Set a break point where you have a reference to the Repository. Look at the debugger for local variables and look at the repository. Is the type your Repository or is it a Proxy. It would be a Proxy if Transactionality was added to it.

Mark
Ray Clark
Ranch Hand

Joined: Aug 16, 2012
Posts: 52
I've seen examples where the @Transactional annotation is in the DAO and I've seen it in the Service class. The Pro Spring 3 book that I have has it in the DAO class although it makes more sense to me to have it in the service. Ok, so I changed it to be in the service which does implement an interface. I also changed the packages to scan property to be:



This did not make a difference in the error message that I am getting.

I am using NetBeans and am not familiar with the debugger. I'll work on trying to get that hooked up and see what it can tell me.

Thank you for your post.
Bill Gorder
Bartender

Joined: Mar 07, 2010
Posts: 1666
    
    7

You do not need the .* on the packages to scan. This will scan sub packages.

Remove this property




You are overriding Spring which sets this to SpringSessionContext.class. If you want Spring to manage things you should not set that.

What Mark is explaining is by default Spring uses an interface based proxy. Therefore if you are going to use the @Transactional annotation and you want it to work properly you need to expose the method through an interface and access it through that interface. It is good programming style to code to interfaces anyway. You can have @Transactionals on the DAO and Service layer if you want.

That said if you want want class based proxies that is an option too but I would not worry about that just yet.

See this thread as well for a similar discussion in the ORM forum.
http://www.coderanch.com/t/590071/ORM/databases/org-hibernate-SessionException-Session-closed


[How To Ask Questions][Read before you PM me]
Bill Gorder
Bartender

Joined: Mar 07, 2010
Posts: 1666
    
    7

Sorry I responded without reading closely. That package scan is on AnnotationSessionFactoryBean that will not scan sub-packages. Use something like this.

Ray Clark
Ranch Hand

Joined: Aug 16, 2012
Posts: 52
Well, I tried to follow your reply and the information in the link that you provided. My error now is:



Here is what the application context file looks like now:



I now have @Transactional in my service class and it implements an interface. Here is what it looks like:



The error occurs in the DAO so I will post it here also:



Thank you for your help.

Ray
Bill Gorder
Bartender

Joined: Mar 07, 2010
Posts: 1666
    
    7

Sorry I did not mean to confuse you with that other link. Do use the AnnotationSessionFactoryBean rather than the LocalSessionFactoryBean like you originally had if you intend to use Hibernate’s annotation support.

The DriverManagerDataSource is overly basic and worthless for anything other than testing. I would consider changing that to at least use apaches BasicDataSource. You might want to set the default auto commit to false on it as well.



The rest of your config looks OK. Do add an interface for your repository and call (and autowire) by the interface not the implementation. Please show us the code that calls your service. Is your service autowired in? How are you creating it? Make sure that everything is a Spring managed bean no uses of the word 'new'.

You might also try adding this to your hibernate properties, if the above suggestions don't help.

Bill Gorder
Bartender

Joined: Mar 07, 2010
Posts: 1666
    
    7

Also I notice you are using MySQL make sure you are using InnoDB and use the more specific MySQLInnoDBDialect
Ray Clark
Ranch Hand

Joined: Aug 16, 2012
Posts: 52
Thank you, but still no luck. I'm still getting the same error message:



My application context now looks like this:



As requested, I added an interface to the repository. Here is the full path of code. This is the Controller class. It has the service interface wired in.



Here is the service implementation class. It has the repository interface wired in.



Here is the repository implementation class.



Should the @Repository and @Service annotations reference the interface name or the implementation name?

It is throwing an exception on the line:


Can you tell what I have wrong?

Thanks,
Ray
Bill Gorder
Bartender

Joined: Mar 07, 2010
Posts: 1666
    
    7

Odd maybe I am falling asleep at the keyboard but I am not seeing the problem. You can drop the proxy-target-class="true", with what you are doing that should not be necessary. How many contexts do you have can you post your web.xml?
Ray Clark
Ranch Hand

Joined: Aug 16, 2012
Posts: 52
Thank you for the reply. Here is my web.xml file:

Ray Clark
Ranch Hand

Joined: Aug 16, 2012
Posts: 52
Am I missing a Spring filter of some kind?

Thanks,
Ray
Bill Gorder
Bartender

Joined: Mar 07, 2010
Posts: 1666
    
    7

Ok so you must have a dispatcher-servlet.xml as well what is in that?
Ray Clark
Ranch Hand

Joined: Aug 16, 2012
Posts: 52
Here is the dispatcher-servlet.xml file.

I tried to separate all of the DB related config into the applicationContext file. Maybe there is a conflict with this file someplace.

Bill Gorder
Bartender

Joined: Mar 07, 2010
Posts: 1666
    
    7

Yup there is your problem. You will have 2 instances of your beans due to your component scanning. In your dispatcher-servlet.xml you should only be scanning the controllers only therefore remove all the component scans from dispatcher-servlet.xml except this one.




Remember that the dispatcher servlet has its own context. The scanning of services and repositories should be in the root context only. I am actually not even sure why you are scanning the domain package at all, seems to me that nothing that is going to be picked up on a component scan should be in that package.
Ray Clark
Ranch Hand

Joined: Aug 16, 2012
Posts: 52
Ok, I took out the component scan tags from the application context file. When I took all of the component scan tags out of the dispatcher servlet file except for the reference to the controller package I got the error:

I added the component scan for the service package to the dispatcher servlet and then I got the following error for the data access object

I added the component scan for the hibernate package to the dispatcher servlet and then I got the same error that I have been getting:

I also moved the component scan for the hibernate package to the application context and still got the No Hibernate Session bound error.

Thanks,
Ray
Bill Gorder
Bartender

Joined: Mar 07, 2010
Posts: 1666
    
    7

Oh yeah sorry about that

applicationContext.xml


dispatcher-servlet.xml



Ray Clark
Ranch Hand

Joined: Aug 16, 2012
Posts: 52
Success.

I now am past my Hibernate configuration problem and can start debugging my data access code.

Thank you so much for your help and patience.

Ray
 
I agree. Here's the link: http://aspose.com/file-tools
 
subject: Trouble converting a Spring JDBC app to use Spring Hibernate