我正在为我的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>
导致此问题的原因是什么?如何解决?
答案 0 :(得分:5)
我可能完全不在这里,但对我来说这似乎是会话处理异常。在@Before
中,您打开和关闭会话,然后在save()
中获得当前会话,这可能是您刚关闭的会话,从而导致异常。如果你不在@Before
中关闭它,请尝试它是否有效(我知道它不是解决方案,只是为了测试理论)。您还可以尝试在存储库中打开新会话,而不是获取当前会话(也不是解决方案)。与我们的工作测试设置相比,我看到的唯一区别是,在@Before
中,我们还调用了标记为@Transactional
的存储库方法,而不是直接创建会话。
答案 1 :(得分:4)
我遇到了类似的错误,除了未知的服务是[org.hibernate.cache.spi.RegionFactory],它只在第二次启动spring上下文时发生。问题是由于org.springframework.transaction.interceptor.TransactionAspectSupport中部分销毁的beanFactory和事务管理器缓存造成的。解决方案是调用org.springframework.transaction.interceptor.TransactionAspectSupport#clearTransactionManagerCache。
答案 2 :(得分:1)
我遇到了同样的错误。我在案件中发现了原因。我的经验可以帮助别人。
我在ServiceRegistryBuilder.destroy()
方法而不是sessionFactoryCreated
方法中调用sessionFactoryClosed
。
基本上,我销毁了我的服务注册表,然后试图获得一个新的会话,这使得Hibernate产生了误导性的错误消息。
因此,我建议如果人们收到此错误,请检查他们是不是关闭了他们的会话或注册表,然后尝试再次获取它。
答案 3 :(得分:1)
对于任何未来的Google搜索者:
当我看到这个问题时,它是由测试开始之前运行的sql脚本中的错误引起的。通过日志向后滚动回来会发现错误,因此值得回顾一下UnknownServiceException
是否只是另一个问题的副作用。
答案 4 :(得分:0)
它没什么,它的缓存问题。只需关闭您的服务器并清理您的tomcat。然后重启。我这样解决了。
答案 5 :(得分:0)
我在Hibernate单元测试创建过程中发现了这个错误。我通过我的util类创建了会话:Session session = XmlSessionUtil.getSessionFactory().openSession();
在一个测试中,会话由session.close();
关闭。当我删除语句结束会话时,所有测试都通过了。所以在我的情况下是异常原因关闭会议。
答案 6 :(得分:0)
在使用休眠框架期间出现此错误。 因此,摆脱了这个错误,我更改了关闭会话和会话工厂的顺序。这样。
session.close();
sessionFactory.close();
对我有用。 希望它对您有用。
答案 7 :(得分:0)
我要在这里加上Ramanpreet Singh的另一个答案。当我在雄猫上使用kill -9
时遇到了这个问题。我可以用这种方式可靠地重现问题。我必须启动服务器,优雅地关闭它,然后再次启动它以解决问题。