我尝试使用内存数据库H2对代码中的事务进行junit测试。 一切都很好 - 从hbm2ddl创建表,执行插入但select返回null。
Junit测试在线失败:
assertNotNull(artifactManager.getArtifact(id));
整个测试
@Test
@Transactional()
@Rollback(true)
public void failTransactionOnUpdateArtifactStateArtifactVerification() throws IllegalStateException, IOException {
//GIVEN
//some initialization already happened
artifactManager.saveArtifact(artifact);
//WHEN
HibernateException exc = Mockito.mock(HibernateException.class);
Mockito.when(historyDao.saveArtifactInHistory(artifact, ver)).thenThrow(exc);
//THEN
//artifact should be present in DB
assertNotNull(artifactManager.getArtifact(id));
assertEquals(artifactManager.getArtifact(id).getState().getType(),StateTypes.SENT);
//and after exception rollback on artifacts Table should be performed and no artifacts should be present in DB
try{
stateService.updateArtifactState( ver,artifact);
}catch(Exception e){
e.printStackTrace();
}
//updateArtifact(artifact); should be rolled back and state reverted to SENT
assertEquals(artifactManager.getArtifact(id).getState().getType(),StateTypes.SENT);
}
控制台日志的相关部分:
2013-01-11 15:02:21,538 INFO [org.hibernate.tool.hbm2ddl.SchemaUpdate] - <schema update complete>
2013-01-11 15:02:21,934 INFO [org.acegisecurity.intercept.AbstractSecurityInterceptor] - <Validated configuration attributes> Hibernate: select artifact0_.Id as Id99_4_, artifact0_.CrosscheckerID as Crossche7_99_4_, artifact0_.CategoryID as CategoryID99_4_, artifact0_.CreationDate as Creation2_99_4_, artifact0_.Description as Descript3_99_4_, artifact0_.FileChecksum as FileChec4_99_4_, artifact0_.ReportID as ReportID99_4_, artifact0_.StateID as StateID99_4_, artifact0_.StateChangeDate as StateCha5_99_4_, artifact0_.Storage as Storage99_4_, user1_.ID as ID86_0_, user1_.Name as Name86_0_, user1_.Surname as Surname86_0_, user1_.username as username86_0_, user1_.jobPositionID as jobPosit5_86_0_, user1_.Email as Email86_0_, user1_.NSNID as NSNID86_0_, user1_.PESEL as PESEL86_0_, user1_.NIP as NIP86_0_, user1_.InProgram as InProgram86_0_, user1_.Employeed as Employeed86_0_, user1_.OutsidePoland as Outside12_86_0_, user1_.Password as Password86_0_, user1_.IncomeCosts as IncomeC14_86_0_, user1_.SupervisorID as Supervi15_86_0_, user1_.Disclosure as Disclosure86_0_, user1_.UserState as UserState86_0_, user1_.FailedLoginAttempts as FailedL18_86_0_, user1_.LastFailedLoginAttempt as LastFai19_86_0_, category2_.ID as ID107_1_, category2_.Name as Name107_1_, category2_."Order" as Order3_107_1_, report3_.ID as ID88_2_, report3_.UserID as UserID88_2_, report3_.StateID as StateID88_2_, report3_.CreationDate as Creation4_88_2_, report3_.StateChangeDate as StateCha5_88_2_, report3_.SupervisorID as Supervis6_88_2_, report3_.AccepterId as AccepterId88_2_, report3_.IncomeCosts as IncomeCo8_88_2_, report3_.AccInProg as AccInProg88_2_, state4_.ID as ID89_3_, state4_.Name as Name89_3_ from Artifacts artifact0_ left outer join Users user1_ on artifact0_.CrosscheckerID=user1_.ID left outer join Categories category2_ on artifact0_.CategoryID=category2_.ID left outer join Reports report3_ on artifact0_.ReportID=report3_.ID left outer join States state4_ on artifact0_.StateID=state4_.ID where artifact0_.Id=?
Hibernate: select max(ID) from Reports
Hibernate: select state0_.ID as ID89_0_, state0_.Name as Name89_0_ from States state0_ where state0_.ID=?
Hibernate: select max(ID) from States
Hibernate: insert into Reports (UserID, StateID, CreationDate, StateChangeDate, SupervisorID, AccepterId, IncomeCosts, AccInProg, ID) values (?, ?, ?, ?, ?, ?, ?, ?, ?)
Hibernate: insert into States (Name, ID) values (?, ?)
Hibernate: insert into Artifacts (Id, CrosscheckerID, CategoryID, CreationDate, Description, FileChecksum, ReportID, StateID, StateChangeDate, Storage) values (null, ?, ?, ?, ?, ?, ?, ?, ?, ?)
Hibernate: select artifact0_.Id as Id99_5_, artifact0_.CrosscheckerID as Crossche7_99_5_, artifact0_.CategoryID as CategoryID99_5_, artifact0_.CreationDate as Creation2_99_5_, artifact0_.Description as Descript3_99_5_, artifact0_.FileChecksum as FileChec4_99_5_, artifact0_.ReportID as ReportID99_5_, artifact0_.StateID as StateID99_5_, artifact0_.StateChangeDate as StateCha5_99_5_, artifact0_.Storage as Storage99_5_, user1_.ID as ID86_0_, user1_.Name as Name86_0_, user1_.Surname as Surname86_0_, user1_.username as username86_0_, user1_.jobPositionID as jobPosit5_86_0_, user1_.Email as Email86_0_, user1_.NSNID as NSNID86_0_, user1_.PESEL as PESEL86_0_, user1_.NIP as NIP86_0_, user1_.InProgram as InProgram86_0_, user1_.Employeed as Employeed86_0_, user1_.OutsidePoland as Outside12_86_0_, user1_.Password as Password86_0_, user1_.IncomeCosts as IncomeC14_86_0_, user1_.SupervisorID as Supervi15_86_0_, user1_.Disclosure as Disclosure86_0_, user1_.UserState as UserState86_0_, user1_.FailedLoginAttempts as FailedL18_86_0_, user1_.LastFailedLoginAttempt as LastFai19_86_0_, category2_.ID as ID107_1_, category2_.Name as Name107_1_, category2_."Order" as Order3_107_1_, report3_.ID as ID88_2_, report3_.UserID as UserID88_2_, report3_.StateID as StateID88_2_, report3_.CreationDate as Creation4_88_2_, report3_.StateChangeDate as StateCha5_88_2_, report3_.SupervisorID as Supervis6_88_2_, report3_.AccepterId as AccepterId88_2_, report3_.IncomeCosts as IncomeCo8_88_2_, report3_.AccInProg as AccInProg88_2_, user4_.ID as ID86_3_, user4_.Name as Name86_3_, user4_.Surname as Surname86_3_, user4_.username as username86_3_, user4_.jobPositionID as jobPosit5_86_3_, user4_.Email as Email86_3_, user4_.NSNID as NSNID86_3_, user4_.PESEL as PESEL86_3_, user4_.NIP as NIP86_3_, user4_.InProgram as InProgram86_3_, user4_.Employeed as Employeed86_3_, user4_.OutsidePoland as Outside12_86_3_, user4_.Password as Password86_3_, user4_.IncomeCosts as IncomeC14_86_3_, user4_.SupervisorID as Supervi15_86_3_, user4_.Disclosure as Disclosure86_3_, user4_.UserState as UserState86_3_, user4_.FailedLoginAttempts as FailedL18_86_3_, user4_.LastFailedLoginAttempt as LastFai19_86_3_, state5_.ID as ID89_4_, state5_.Name as Name89_4_ from Artifacts artifact0_ left outer join Users user1_ on artifact0_.CrosscheckerID=user1_.ID left outer join Categories category2_ on artifact0_.CategoryID=category2_.ID left outer join Reports report3_ on artifact0_.ReportID=report3_.ID left outer join Users user4_ on report3_.UserID=user4_.ID left outer join States state5_ on artifact0_.StateID=state5_.ID where artifact0_.Id=?
2013-01-11 15:02:22,213 INFO [org.hibernate.impl.SessionFactoryImpl] - <closing>
我已按如下方式配置数据库:
<bean id="dataSource"
class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="org.h2.Driver" />
<property name="url" value="jdbc:h2:mem:taxMemDB;DB_CLOSE_DELAY=-1" />
<property name="username" value="sa" />
<property name="password" value="" />
</bean>
<bean id="taxSessionFactory" class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean" >
<property name="AnnotatedClasses">
<list> ...</list>
</property>
<property name="dataSource" ref="dataSource" />
<property name="mappingResources">
<list>
<value>mapping.hbm.xml</value>
</list>
</property>
<property name="hibernateProperties">
<value>
hibernate.dialect=org.hibernate.dialect.H2Dialect
hibernate.connection.charSet=UTF-8
hibernate.connection.pool_size=15
hibernate.show_sql=true
hibernate.hbm2ddl.auto=update
</value>
</property>
</bean>
<bean id="hibernateTemplate"
class="org.springframework.orm.hibernate3.HibernateTemplate">
<property name="sessionFactory">
<ref bean="taxSessionFactory" />
</property>
</bean>
有什么线索可能有什么不对?或者我应该附加更多代码?
- 请求的代码 ArtifactManager:
public Artifact getArtifact(long artifactId) {
Artifact artifact = artifactDao.getArtifact(artifactId);
return artifact;
}
ArtifactDao:
@Override
public Artifact getArtifact(Long id) {
Session session = sessionFactory.getCurrentSession();
return (Artifact) session.get(Artifact.class, id);
}
ArtifactManager.saveArifact:
@Transactional(rollbackFor = Exception.class)
public boolean saveArtifact(Artifact artifact)throws IOException {
String checksum = null;
String userPath = null;
checksum = checksumGenerator.generateChecksum(artifact.getFile().getInputStream());
userPath = storageManager.upload(artifact);
artifact.setStoragePath(userPath);
artifact.setFileChecksum(checksum);
if(artifact.getId()!=null){
return artifactDao.mergeArtifact(artifact);
}else{
return artifactDao.saveOrUpdateArtifact(artifact);
}
}
ArifactDao部分
@Override
public boolean saveOrUpdateArtifact(Artifact artifact) {
Session session = sessionFactory.getCurrentSession();
try {
session.saveOrUpdate(artifact);
} catch (DataAccessException ex) {
log.error(ex.getMessage());
return false;
}
return true;
}
@Override
public boolean mergeArtifact(Artifact artifact) {
Session session = sessionFactory.getCurrentSession();
try {
session.merge(artifact);
} catch (DataAccessException ex) {
log.error(ex.getMessage());
return false;
}
return true;
}
答案 0 :(得分:0)
我认为您的方法ArtifactManager.getArtifact(id)
正在直接查看数据库,因为您的事务尚未提交......它什么也没找到。
请注意,@Rollback(true)
表示您的交易永远不会被提交。
修改强>
根据你的代码,似乎你正在寻找当前的会话以找到工件(所以它是没有提交事务的OK事件)。
其他一些可用于检查的代码:
saveArtifact
方法的代码是什么?修改强>
我发现你的代码有些烦人的事情:
您正在呼叫saveArtifact
,但不检查返回值。在做其他任何事情之前,最好先检查一下。像assertTrue(artifactManager.saveArtifact(artifact)));
通常,在合并一个实例时,将合并后的实例返回是很有趣的...但是在你的DAO中你会忘记它并返回一个布尔值。见merge API,真正有趣的部分是这个
给定的实例(即参数)不会与会话相关联。