Testing DAO

163 views
Skip to first unread message

master....@gmail.com

unread,
Apr 27, 2013, 5:03:58 PM4/27/13
to java-gen...@googlegroups.com
Hi,

Long story short, I have been recently learning Spring and hibernate seemed an obvious choice to handle the persistent layer.

I saw his library which looks great. However when I set out to test my DAO by initialising the app context and try to persist an entity, I get an error with the full stack trace being:

Exception in thread "main" org.hibernate.HibernateException: No Session found for current thread

at org.springframework.orm.hibernate4.SpringSessionContext.currentSession(SpringSessionContext.java:97)

at org.hibernate.internal.SessionFactoryImpl.getCurrentSession(SessionFactoryImpl.java:980)

at com.googlecode.genericdao.dao.hibernate.HibernateBaseDAO.getSession(HibernateBaseDAO.java:68)

at com.googlecode.genericdao.dao.hibernate.HibernateBaseDAO._saveOrUpdateIsNew(HibernateBaseDAO.java:159)

at com.googlecode.genericdao.dao.hibernate.GenericDAOImpl.save(GenericDAOImpl.java:101)

at sample.test.Test.main(Test.java:26)


When I say test, it was not a unit test in a traditional sense. Just a main method just so I can get a good feel of the library and play around with it. I thought it may be my configuration so I decide to pull in the sample project and do the same. 

Unfortunately I get the same result. However, when grabbing a Service bean, e.g. Town/Citizen Service, I am able to persist data just fine. I noticed the @Transactional config on the class level of the service objects and that could be a reason.

Placing this config on the class level of the DAO makes no difference.

However, for testing the dao themselves, for example if I did decide to set up proper unit tests, how would I go about this?

Hope you can shed some insight or point out any misunderstanding.

My setup is Spring 3.2 & Hibernate 4.

I have come across this:

But how would I go about making the DAO transaction aware. Being new to these frameworks, I am not so sure?

master....@gmail.com

unread,
Apr 27, 2013, 5:31:04 PM4/27/13
to java-gen...@googlegroups.com, master....@gmail.com
Apologies for the double post. Just thought it might be useful to state the reason for this.

If for example, I may have the need to maintain complex database queries, testing the DAOs themselves could prove very useful.

David W

unread,
Apr 28, 2013, 9:56:10 PM4/28/13
to java-gen...@googlegroups.com, master....@gmail.com
Yeah. This definitely looks points to not having a transaction going. As you noticed, Spring will take care of the transactions for you if you use the @Transactional annotation and if you can get it configured correctly. This tutorial might help you with that (http://www.byteslounge.com/tutorials/spring-with-hibernate-persistence-and-transactions-example).

Also Spring has good support for transaction handling in unit tests as well. You'll need to look up more comprehensive documentation, but the basic idea is that if you use...
@RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(locations = ...)
on your unit test you can just slap @Transactional on the unit test class or method and it will work (again, provided you get spring transaction handling setup correctly).

Hope that helps.

-- David
Message has been deleted

master....@gmail.com

unread,
Apr 29, 2013, 6:30:11 PM4/29/13
to java-gen...@googlegroups.com, master....@gmail.com
Original post:
Hi David,

Thanks for your quick reply.

Looking at the first link, the reason why that example works is the implementation of the DAO is specified as a Service component and after a little background reading, Spring applies transactions on service components and that is why that example works.

I will try to verify whether using this annotation solves the problem but it seems weird annotating a DAO impl as a Service instead of a repository. This seems true as using service layer beans annotated @Transactional and @Service, there was no issue in persisting / querying.

I have tried using @RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(locations = ...) and using @Transactional on the unit test class + methods but I still ran into the same issue.

I finally did get it to work by having a base test class which initialises the context. Then included a method in the base test class that creates a transaction before each test. The only thing I need to do is handle that open transaction after each test. The only issue is being new to these frameworks, I am not sure whether this is recommended.

Kind regards,

Bennett

Update:

Hi David,

Can you take a look at the org.timesheet.h4 project under:


The two test of interest is org.timesheet.service.dao.EmployeeDaoTestng.

Incase you do not want to download this project and run this test here is what is going on:
- there are 6 tests
- 5 of them test an EmployeeDAO implementation that implements extends an simple supplied HibernateDao & GenericDAOImpl. 
- The remainder tests a PersonDAO (an implementation of IPerson) both of which extend and implement this libraries GenericDAO and GenericDAOImpl.
- The 5 tests pass but the PersonDAO test fails with the same reason I have mentioned in this thread.
- I noticed the HibernateDao had @Transactional(propagation= Propagation.REQUIRED, readOnly=false), but placing the same annotation over the PersonDAO had no effect.

Hopefully you can help with this.
Reply all
Reply to author
Forward
0 new messages