I am trying to use spring, junit to test the DAO method. I have seen some methods on the Internet that use spring's declarative transaction management (i.e. @Transactional) for transaction operations. , saying that after the test is completed, spring will roll back the test method, thereby achieving the purpose of testing.
Then I followed this approach to test the method of adding operations in dao, and found that after the transaction was submitted, the rollback was not successful, and there was extra data in the database that I tested. At first I thought it was because spring did not perform rollback, but later I observed the console print information and found that there was rollback information, but why it failed was not clear. I found some related solutions, but I found that they didn't solve my problem. I'm very troubled, so I came here to ask you for help. I hope you can give me some advice.
The following is my code and corresponding configuration
DAOImpl’s addUser() method
@Override
public void addUser(User u) {
Session session = sessionFactory.openSession();
Transaction tc = session.getTransaction();
try {
tc.begin();
session.save(u);
tc.commit();
}catch(Exception e){
tc.rollback();
e.printStackTrace();
}
return ;
}
Daos.xml file corresponding configuration
<bean id="txManager"
class="org.springframework.orm.hibernate5.HibernateTransactionManager">
<property name="sessionFactory" ref="mySessionFactory" />
</bean>
<tx:annotation-driven transaction-manager="txManager" />
Test class
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations={"/services.xml"})
@Transactional(transactionManager = "txManager")
@Rollback(true)
public class UserServiceImplTest {
@Autowired
UserDAO userDAO; //自动装配userDAO
@Test
public void testAddUse(){
User u = new User();
u.setLevel(3);
u.setName("ab11");
u.setPassword("hh");
userDAO.addUser(u);
Assert.assertEquals(u.getName(), userDAO.getUserList().get(userDAO.getUserList().size()-1).getName());
}
Part of the console printing information
信息: Using DataSource [org.apache.commons.dbcp2.BasicDataSource@498d318c] of Hibernate SessionFactory for HibernateTransactionManager
六月 02, 2017 4:46:19 下午 org.springframework.test.context.transaction.TransactionContext startTransaction
信息: Began transaction (1) for test context [DefaultTestContext@52d6cd34 testClass = UserServiceImplTest, testInstance = com.dxzh.mall.serviceImpl.test.UserServiceImplTest@715d6168, testMethod = testAddUse@UserServiceImplTest, testException = [null], mergedContextConfiguration = [MergedContextConfiguration@75798d03 testClass = UserServiceImplTest, locations = '{classpath:/services.xml}', classes = '{}', contextInitializerClasses = '[]', activeProfiles = '{}', propertySourceLocations = '{}', propertySourceProperties = '{}', contextCustomizers = set[[empty]], contextLoader = 'org.springframework.test.context.support.DelegatingSmartContextLoader', parent = [null]]]; transaction manager [org.springframework.orm.hibernate5.HibernateTransactionManager@c6634d]; rollback [true]
Fri Jun 02 16:46:19 CST 2017 WARN: Establishing SSL connection without server's identity verification is not recommended. According to MySQL 5.5.45+, 5.6.26+ and 5.7.6+ requirements SSL connection must be established by default if explicit option isn't set. For compliance with existing applications not using SSL the verifyServerCertificate property is set to 'false'. You need either to explicitly disable SSL by setting useSSL=false, or set useSSL=true and provide truststore for server certificate verification.
Hibernate: insert into user (name, password, level) values (?, ?, ?)
六月 02, 2017 4:46:19 下午 org.springframework.test.context.transaction.TransactionContext endTransaction
信息: Rolled back transaction for test context [DefaultTestContext@52d6cd34 testClass = UserServiceImplTest, testInstance = com.dxzh.mall.serviceImpl.test.UserServiceImplTest@715d6168, testMethod = testAddUse@UserServiceImplTest, testException = java.lang.RuntimeException, mergedContextConfiguration = [MergedContextConfiguration@75798d03 testClass = UserServiceImplTest, locations = '{classpath:/services.xml}', classes = '{}', contextInitializerClasses = '[]', activeProfiles = '{}', propertySourceLocations = '{}', propertySourceProperties = '{}', contextCustomizers = set[[empty]], contextLoader = 'org.springframework.test.context.support.DelegatingSmartContextLoader', parent = [null]]].
六月 02, 2017 4:46:19 下午 org.springframework.context.support.GenericApplicationContext doClose
信息: Closing org.springframework.context.support.GenericApplicationContext@3ffc5af1: startup date [Fri Jun 02 16:46:13 CST 2017]; root of context hierarchy
typecho2017-06-12 09:27:30
Transactional is a service layer transaction. If you use it, you don’t have to write transactions at the DAO layer