6

AbstractHibernateRepository 保存メソッドの単体テストを作成しています。私は春のテストランナーを使用していますが、実行時に次の例外が発生します:

org.hibernate.service.UnknownServiceException: Unknown service requested [org.hibernate.engine.jdbc.connections.spi.ConnectionProvider]
at org.hibernate.service.internal.AbstractServiceRegistryImpl.getService(AbstractServiceRegistryImpl.java:201)

私のテスト:

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("file:src/main/webapp/WEB-INF/spring/spring-hibernate.xml")
public class AbstractHibernateRepoTest extends AbstractHibernateRepo<Video> {
    @Autowired private SessionFactory sessionFactory;
    private Video video;

    public AbstractHibernateRepoTest() 
    {
        super(Video.class);
    }

    @Before
    public void setUp ()
    {
        video = new Video();
        video.setId("xyz");
        video.setName("Video Name");
        video.setSrc("Source");
        video.setThumbnail("Thumbnail");
        Session session = sessionFactory.openSession();
        session.beginTransaction();
        session.save(video) ;
        session.close();
    }

    @Test
    public void testSaveMethod ()
    {
        video.setId("asa");
        String id = (String) save(video);
        Assert.assertEquals(video.getId(), id);
    }

    @After
    public void breakDown ()
    {
        sessionFactory.close();
    }
}

リポジトリ:

    @Autowired private SessionFactory sessionFactory;
    private final Class<T> clazz;

    public AbstractHibernateRepo(Class<T> clazz) 
    {
        this.clazz = clazz;
    }

    @SuppressWarnings("unchecked")
    @Transactional(rollbackFor = HibernateException.class)
    @Override
    public T findById(Serializable id) 
    {
        if (id == null)
            throw new NullPointerException();

        return (T) getSessionFactory().getCurrentSession().get(getClazz(), id);
    }

    @Override
    @Transactional(rollbackFor = HibernateException.class)
    public Serializable save(T entity) 
    {
        if (entity == null)
            throw new NullPointerException();

        return getSessionFactory().getCurrentSession().save(entity);
    }

    @Override
    @Transactional(rollbackFor = HibernateException.class)
    public void delete(T entity) 
    {
        if (entity == null)
            throw new NullPointerException();

        getSessionFactory().getCurrentSession().delete(entity);
    }

    @Override
    @Transactional(rollbackFor = HibernateException.class)
    public void update(T entity) 
    {
        if (entity == null)
            throw new NullPointerException();

        getSessionFactory().getCurrentSession().update(entity);
    }
}

春の設定:

<tx:annotation-driven transaction-manager="transactionManager"/> 

<!-- Root Context: defines shared resources visible to all other web components -->
<bean id="dataSource" class="org.apache.commons.dbcp2.BasicDataSource">
    <property name="driverClassName" value="org.h2.Driver"/>
    <property name="url" value="jdbc:h2:mem:db1;DB_CLOSE_DELAY=-1;MVCC=TRUE"/>
    <property name="username" value="someuser"/>
    <property name="password" value="somepassword"/>
</bean>

<bean id="sessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
    <property name="dataSource" ref="dataSource"/>
    <property name="packagesToScan" value="com.package.model"/>
    <property name="hibernateProperties">
        <props>
            <prop key="hibernate.show_sql">true</prop>
            <prop key="hibernate.hbm2ddl.auto">update</prop>
            <prop key="hibernate.dialect">org.hibernate.dialect.H2Dialect</prop>
        </props>
    </property>
</bean>

<bean id="transactionManager" class="org.springframework.orm.hibernate4.HibernateTransactionManager">
    <property name="sessionFactory" ref="sessionFactory"/>
    <property name="dataSource" ref="dataSource"/>
</bean>

この問題の原因は何ですか?どうすれば修正できますか?

4

8 に答える 8

6

私はここで完全に外れているかもしれませんが、私にはこれはセッション処理の例外のようです。@Beforeセッションを開いて閉じると、現在のセッションが取得されます。これsave()は、閉じたばかりのセッションである可能性があり、例外が発生します。閉じない場合に機能するかどうか試してください@Before(理論をテストするためだけに、それが解決策ではないことはわかっています)。現在のセッションを取得する代わりに、リポジトリで新しいセッションを開いてみることもできます (これも解決策ではありません)。作業中のテスト セットアップと比較してわかる唯一の違いは、セッションを直接作成する代わりに、@Beforeとしてマークされたリポジトリ メソッドも呼び出すことです。@Transactional

于 2014-10-20T15:49:41.777 に答える
2

将来の Google 検索ユーザー向け:

この問題が発生したのは、テスト開始前に実行されていた SQL スクリプトのエラーが原因でした。ログを十分に遡ってスクロールすると、エラーが明らかになったので、もう一度調べて、UnknownServiceException別の問題の単なる副作用ではないことを確認する価値があります。

于 2015-10-13T14:42:25.110 に答える
2

私はこの同じエラーに遭遇しました。私の場合、原因がわかりました。私の経験が誰かの役に立つかもしれません。

私は自分のメソッドではなくServiceRegistryBuilder.destroy()自分のメソッドを呼び出していました。sessionFactoryCreatedsessionFactoryClosed

基本的に、サービス レジストリを破棄してから新しいセッションを取得しようとしたため、Hibernate で誤解を招くエラー メッセージが生成されました。

したがって、このエラーが発生した場合は、セッションまたはレジストリを閉じていないことを確認してから、もう一度エラーを取得しようとすることをお勧めします。

于 2015-05-28T16:03:35.223 に答える