views:

26

answers:

1

Hello,

I've read spring documentation regarding Hibernate's setComplete() method while working with Unit Test Cases. I am confused between setComplete() versus session's flush() method. Both are responsible to make object's state persistent in Database by loading from memory to actual Database. It will be great if somebody can help me to get good resources/examples regarding the same. I will highly appreciate it.

Thanks, Maulik

+2  A: 

To my knowledge, setComplete() is not part of Hibernate's API (please provide a link when you are referring to something), it is part of the API of AbstractTransactionalSpringContextTests which is a convenient base class for JUnit 3.8 based tests that should occur in a transaction, but normally will roll the transaction back on the completion of each test. The setComplete() method allows to alter this default transactional behavior. From its Javadoc:

Cause the transaction to commit for this test method, even if default is set to rollback.

The following section of the documentation gives more concrete use cases:

8.3.6.3. Transaction management

AbstractTransactionalSpringContextTests depends on a PlatformTransactionManager bean being defined in the application context. The name doesn't matter due to the use of autowire by type.

Typically you will extend the subclass, AbstractTransactionalDataSourceSpringContextTests. This class also requires that a DataSource bean definition - again, with any name - be present in the application context. It creates a JdbcTemplate instance variable, that is useful for convenient querying, and provides handy methods to delete the contents of selected tables (remember that the transaction will roll back by default, so this is safe to do).

If you want a transaction to commit programmatically - unusual, but occasionally useful when you want a particular test to populate the database - you can call the setComplete() method inherited from AbstractTransactionalSpringContextTests. This will cause the transaction to commit instead of roll back. As an alternative, if you are developing against Java 5 or greater and extending AbstractAnnotationAwareTransactionalTests, you may annotate your test method with @Rollback(false) to achieve the same effect through configuration.

There is also the convenient ability to end a transaction before the test case ends, by calling the endTransaction() method. This will roll back the transaction by default and commit it only if setComplete() had previously been called. This functionality is useful if you want to test the behavior of 'disconnected' data objects, such as Hibernate-mapped entities that will be used in a web or remoting tier outside a transaction. Often, lazy loading errors are discovered only through UI testing; if you call endTransaction() you can ensure correct operation of the UI through your JUnit test suite.

Hibernate's Session#flush() is very different, it just tells Hibernate to write pending changes to the database, it doesn't interact with the transaction.

Pascal Thivent