1

我正在尝试使用内存数据库 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;
}

神器道:

@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;
}
4

1 回答 1

0

我认为您的方法ArtifactManager.getArtifact(id)是直接查看数据库,并且由于您的事务尚未提交......它什么也没找到。

请注意,这@Rollback(true)意味着您的事务将永远不会被提交。

编辑

根据您的代码,您似乎正在寻找当前会话以查找工件(因此,未提交事务的 OK 事件)。

其他一些对检查有用的代码:

  • 你如何在你的映射中指定 artifact 的 id ?(自动生成或手动定义?)
  • 你的saveArtifact方法的代码是什么?

编辑

我在您的代码中发现了一些烦人的事情:

  • 您正在调用saveArtifact,但您不检查返回值。在做任何其他事情之前最好检查一下。就像是assertTrue(artifactManager.saveArtifact(artifact)));

  • 通常,当合并一个实例时,取回合并的实例是很有趣的……但是在你的 DAO 中你忘记了它并返回一个布尔值。见merge API,真正有趣的部分是这个

给定的实例(即参数)不会与会话相关联

  • 根据您的评论,工件初始化为 id=10L。因此,您将调用 session.merge 方法。但是您的工件不应该在会话中,也不应该在数据库中......所以我认为您应该在某处有一些相关的错误日志?不 ?
于 2013-01-11T15:05:55.413 回答