AbstractHibernateRepository保存メソッドの単体テストを作成しています。 Spring Test Runnerを使用していますが、実行すると次の例外が発生します。
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);
}
}
Spring Config:
<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>
この問題の原因とその修正方法を教えてください。
私はここから完全に離れているかもしれませんが、私にはこれはセッション処理の例外のようです。 _@Before
_でセッションを開いて閉じ、次にsave()
で現在のセッションを取得します。これはおそらく閉じたばかりのセッションであり、例外が発生します。 _@Before
_で閉じない場合に機能するかどうか試してください(理論をテストするためだけに、解決策ではないことはわかっています)。現在のセッションを取得する代わりに、リポジトリで新しいセッションを開いてみることもできます(これもソリューションではありません)。作業中のテストセットアップと比較した唯一の違いは、_@Before
_では、セッションを直接作成する代わりに、_@Transactional
_とマークされたリポジトリメソッドも呼び出すことです。
不明なサービスが[org.hibernate.cache.spi.RegionFactory]であったことを除いて、同様のエラーが発生しました。これは、Springコンテキストが2回目に開始されたときにのみ発生しました。この問題は、org.springframework.transaction.interceptor.TransactionAspectSupportのbeanFactoryとトランザクションマネージャーのキャッシュが部分的に破壊されたことが原因でした。解決策は、org.springframework.transaction.interceptor.TransactionAspectSupport#clearTransactionManagerCacheを呼び出すことでした。
私はこれと同じエラーに遭遇しました。私の場合、原因を発見しました。私の経験は他の誰かを助けるかもしれません。
sessionFactoryCreated
メソッドではなくsessionFactoryClosed
メソッドでServiceRegistryBuilder.destroy()
を呼び出していました。
基本的に、サービスレジストリを破棄してから、新しいセッションを取得しようとしました。これにより、Hibernateは誤解を招くエラーメッセージを生成します。
したがって、このエラーが発生した場合は、セッションまたはレジストリを閉じていないことを確認してから、もう一度取得することをお勧めします。
今後のGoogle検索者向け:
この問題が発生したのは、テストが開始される前に実行されていたSQLスクリプトのエラーが原因でした。ログを十分にスクロールして戻るとエラーが明らかになったので、UnknownServiceException
が別の問題の単なる副作用ではないことを確認する価値があります。
ここで、RamanpreetSinghからの別の回答を追加します。 Tomcatでkill -9
を使用したときに、この問題が発生しました。この方法で問題を確実に再現できます。サーバーを起動し、正常に閉じてから、もう一度起動して問題を解決する必要があります。
その何もない、そのキャッシュの問題。サーバーを閉じてTomcatをクリーンアップするだけです。その後、再起動します。このように解決しました。
Hibernateフレームワークでの作業中にこのエラーが発生しました。したがって、このエラーを取り除くために、セッションとセッションファクトリを閉じる順序を変更します。このような。
session.close();
sessionFactory.close();
それは私のために働いた。それがあなたのために働くことを願っています。
Hibernateユニットテストの作成中にこのエラーを発見しました。 utilクラスでセッションを作成しました:Session session = XmlSessionUtil.getSessionFactory().openSession();
1つのテストで、session.close();
によってセッションが閉じられました。ステートメントを閉じるセッションを削除すると、すべてのテストに合格しました。だから私の場合は例外的な理由でセッションを閉じました。