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

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

1 に答える 1

0

あなたのメソッドArtifactManager.getArtifact(id)はデータベースを直接調べていると思いますが、トランザクションはまだコミットされていないため、何も見つかりません。

@Rollback(true)これは、トランザクションがコミットされないことを意味することに注意してください。

編集

あなたのコードによると、アーティファクトを見つけるために現在のセッションを探しているようです(したがって、コミットされていないトランザクションではOKイベントです)。

検査に役立つ可能性のある他のコード:

  • マッピングでアーティファクトのIDをどのように指定しますか?(自動生成または手動で定義されていますか?)
  • あなたのsaveArtifactメソッドのコードは何ですか?

編集

私はあなたのコードでいくつかの厄介なことを見つけました:

  • あなたは電話をかけsaveArtifactていますが、戻り値をチェックしていません。他のことをする前にチェックする方がおそらく良いでしょう。何かのようなものassertTrue(artifactManager.saveArtifact(artifact)));

  • 通常、インスタンスをマージするとき、マージされたインスタンスを元に戻すのは興味深いことです...しかし、DAOでは、それを忘れて、代わりにブール値を返します。マージAPIを参照してください。本当に興味深い部分はこれです

指定されたインスタンス(つまり、パラメーター)はセッションに関連付けられません

  • あなたのコメントによると、アーティファクトはid=10Lで初期化されます。したがって、session.mergeメソッドを呼び出します。しかし、アーティファクトはセッションにもDBにも存在しないはずです...したがって、関連するエラーログをどこかに置く必要があると思いますか?いいえ ?
于 2013-01-11T15:05:55.413 に答える