-->
These old forums are deprecated now and set to read-only. We are waiting for you on our new forums!
More modern, Discourse-based and with GitHub/Google/Twitter authentication built-in.

All times are UTC - 5 hours [ DST ]



Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 10 posts ] 
Author Message
 Post subject: Transactional Unit tests with Search
PostPosted: Tue Jun 29, 2010 7:43 pm 
Newbie

Joined: Wed May 19, 2010 7:26 pm
Posts: 4
I am trying to take advantage of Spring's Transactional support in unit tests. I define a transaction manager to rollback after each test using the spring test annotations.
My intention is to create entities in setUp method, execute the test method and rollback the test data after test execution (using rollback).
Spring does good job as far as the DB is concerned. But hibernate search doesn't index the objects as there is no commit on the entities created during setUp (due to defaultRollback parameter).

As the transaction manager doesn't commit the data to the DB, I am not able to test hibernate search queries.
Is there a workaround to setup my tests using Spring's transactional test capabilities to rollback DB/lucene index after each test with out restoring the DB/index through the hard way(tearDown)?

I have the following annotations in my test case where I would like to setup my entities in the DB (setUp method), execute DB queries as part of the same transaction, search the lucene index using hibernate search as part of the same uncommitted transaction (test methods) and let spring handle the rollback of the db and purge the lucene indices as part of rollback.

Code:
RunWith( SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = {"classpath:spring-config.xml"})
@TestExecutionListeners({DependencyInjectionTestExecutionListener.class,
        TransactionalTestExecutionListener.class})
@TransactionConfiguration(transactionManager="transactionManager",
                defaultRollback=true)
@Transactional
public class EmployeeTest extends TestCase


Last edited by rajvissa on Wed Jun 30, 2010 12:40 pm, edited 1 time in total.

Top
 Profile  
 
 Post subject: Re: Transactional Unit tests with Search
PostPosted: Wed Jun 30, 2010 5:15 am 
Hibernate Team
Hibernate Team

Joined: Thu Apr 05, 2007 5:52 am
Posts: 1689
Location: Sweden
First of all I would not recommend this type of setup. I think it is important to make the tests match the actual use cases and there you are committing the data. Why not use a in memory database for testing? This makes it also easy to avoid any data dependencies between tests, because the database gets recreated between tests. For setting up a initial state dbunit could be used.

That said, you probably can make your usecase work by implementing a custom Worker. Per default Search uses a so called TransactionalWorker which will batch all work until a transaction commits or if not transaction exists executes updates directly. You custom Worker should look exactly like TransactionalWorker except that it should always execute the updates directly. You can see the code for TransactionalWorker here. You can specify your custom worker using the hibernate.search.worker.scope property specifying the fully qualified class name of your implementation.

--Hardy


Top
 Profile  
 
 Post subject: Re: Transactional Unit tests with Search
PostPosted: Wed Jun 30, 2010 5:17 am 
Hibernate Team
Hibernate Team

Joined: Fri Oct 05, 2007 4:47 pm
Posts: 2536
Location: Third rock from the Sun
Quote:
But hibernate search doesn't index the objects as no commit is called (due to defaultRollback parameter).

Cool, it means you configured Hibernate & Spring to interact correctly; many people get that wrong.

Quote:
Is there a workaround how I can setup my tests to use the spring transactional test capabilities to rollback the db/lucene index after each test with out restoring the db/index through the hard way(tearDown)?

Code:
FullTextSession :
public void flushToIndexes();
public <T> void purgeAll(Class<T> entityType);

flush the index operations to be able to test queries, but then you'll likely need the purgeAll to empty the index completely, or the purge(Class<T> entityType, Serializable id) to purge specific objects. Once written to the index, it can't be rolled back so you have to cleanup some way, but index operations are very fast.

_________________
Sanne
http://in.relation.to/


Top
 Profile  
 
 Post subject: Re: Transactional Unit tests with Search
PostPosted: Wed Jun 30, 2010 5:19 am 
Hibernate Team
Hibernate Team

Joined: Thu Apr 05, 2007 5:52 am
Posts: 1689
Location: Sweden
Right, FullTextSession.flushToIndexes() seems much easier :)


Top
 Profile  
 
 Post subject: Re: Transactional Unit tests with Search
PostPosted: Wed Jun 30, 2010 11:23 am 
Newbie

Joined: Wed May 19, 2010 7:26 pm
Posts: 4
hardy.ferentschik wrote:
First of all I would not recommend this type of setup. I think it is important to make the tests match the actual use cases and there you are committing the data. Why not use a in memory database for testing? This makes it also easy to avoid any data dependencies between tests, because the database gets recreated between tests. For setting up a initial state dbunit could be used.
--Hardy

Shouldn't the unit test be independent of other tests? I persist some entities in the DB as part of setUp. These should obviously be removed as part of tearDown (called after each test execution). The issue I have is as I am not committing the transactions, I am unable to perform hibernate search. How can I perform search with in a unit test?

I will take a look at the TransactionalWorker as you suggested. Hope I am clear what I intend to do?


Top
 Profile  
 
 Post subject: Re: Transactional Unit tests with Search
PostPosted: Wed Jun 30, 2010 12:13 pm 
Hibernate Team
Hibernate Team

Joined: Fri Oct 05, 2007 4:47 pm
Posts: 2536
Location: Third rock from the Sun
Quote:
Shouldn't the unit test be independent of other tests?

Yes, that's why the best approach is as Hardy suggested to use an in-memory database and index, to have a totally new one for each test.
It's the only way to test your modules including transactional behaviour - or I assume you never test the rollback rules.
If you checkout Hibernate Search you can see how all unit tests do create in-memory resources and recreate a new schema for each scenario.

If you prefer to use the rollback pattern, try flushToIndexes() as mentioned above.

_________________
Sanne
http://in.relation.to/


Top
 Profile  
 
 Post subject: Re: Transactional Unit tests with Search
PostPosted: Wed Jun 30, 2010 12:33 pm 
Newbie

Joined: Wed May 19, 2010 7:26 pm
Posts: 4
I agree with you. The reason for hibernate search not working for me is due to the absence of commit on the transaction. Hibernate search does index only committed data and due to the Spring's @TransactionConfiguration(transactionManager="transactionManager", defaultRollback=true) annotation it doesn't commit the transaction to perform a rollback after the test execution.

Is there a way to suggest hibernate search to index the uncommitted data with in the same transaction and be able to search the indices? Once we(spring) rollback the transaction lucene flushes the indices?

Currently we perform a commit after setUp (implicit commit) and perform search and clean the entities persisted in the tearDown which we don't want to do. I am looking to take the advantage of Spring's defaultRollback option so that I don't explicitly commit/rollback through code.

The Hibernate search tests do a explicit commit and flush indices after each test. In my case there is no commit


Top
 Profile  
 
 Post subject: Re: Transactional Unit tests with Search
PostPosted: Mon Jul 05, 2010 2:02 am 
Newbie

Joined: Mon Jul 05, 2010 1:59 am
Posts: 2
rajvissa wrote:
I agree with you. The reason for hibernate search not working for me is due to the absence of commit on the transaction. Hibernate search does index only committed data and due to the Spring's @TransactionConfiguration(transactionManager="transactionManager", defaultRollback=true) annotation it doesn't commit the transaction to perform a rollback after the test execution.

Is there a way to suggest hibernate search to index the uncommitted data with in the same transaction and be able to search the indices? Once we(spring) rollback the transaction lucene flushes the indices?

Currently we perform a commit after setUp (implicit commit) and perform search and clean the entities persisted in the tearDown which we don't want to do. I am looking to take the advantage of Spring's defaultRollback option so that I don't explicitly commit/rollback through code.

The Hibernate search tests do a explicit commit and flush indices after each test. In my case there is no commit


I have the same problem, Can you paste some code to help me?


Top
 Profile  
 
 Post subject: Re: Transactional Unit tests with Search
PostPosted: Mon Jul 05, 2010 2:40 am 
Newbie

Joined: Mon Jul 05, 2010 1:59 am
Posts: 2
jotadeveloper wrote:
rajvissa wrote:
I agree with you. The reason for hibernate search not working for me is due to the absence of commit on the transaction. Hibernate search does index only committed data and due to the Spring's @TransactionConfiguration(transactionManager="transactionManager", defaultRollback=true) annotation it doesn't commit the transaction to perform a rollback after the test execution.

Is there a way to suggest hibernate search to index the uncommitted data with in the same transaction and be able to search the indices? Once we(spring) rollback the transaction lucene flushes the indices?

Currently we perform a commit after setUp (implicit commit) and perform search and clean the entities persisted in the tearDown which we don't want to do. I am looking to take the advantage of Spring's defaultRollback option so that I don't explicitly commit/rollback through code.

The Hibernate search tests do a explicit commit and flush indices after each test. In my case there is no commit


I have the same problem, Can you paste some code to help me?


public void flushIndexes(){
final FullTextSession fullTextSession = Search.getFullTextSession(getHibernateTemplate().getSessionFactory().getCurrentSession());
fullTextSession.flushToIndexes();
}

I call this method before test. And works for me.


Top
 Profile  
 
 Post subject: Re: Transactional Unit tests with Search
PostPosted: Wed Jul 07, 2010 8:15 pm 
Newbie

Joined: Wed May 19, 2010 7:26 pm
Posts: 4
But you can search using hibernate search as the transaction is not committed. If I explicitly commit the transaction then I can search flush indices.
However then I am not using the Springs @TransactionConfiguration hook. Its more like a persistent transaction and I need to remove my entities manually in the tearDown method of the test that I want to avoid.


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 10 posts ] 

All times are UTC - 5 hours [ DST ]


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum

Search for:
© Copyright 2014, Red Hat Inc. All rights reserved. JBoss and Hibernate are registered trademarks and servicemarks of Red Hat, Inc.