【问题标题】:org.hibernate.LazyInitializationException: could not initialize proxy -no Sessionorg.hibernate.LazyInitializationException:无法初始化代理 - 无会话
【发布时间】:2013-08-19 12:53:05
【问题描述】:

当我为 Spring 应用程序运行测试用例(Junit)时,我遇到了这个错误。

我搜索了这个问题,我得到的信息是每当发生延迟初始化并且我的应用程序在会话关闭时尝试获取二级数据(对象分离)然后发生此错误,我们无法将初始化设置为 EAGER作为其性能问题。

我的测试类包含:

@RunWith(SpringJUnit4ClassRunner.class)
public class MyTestClass extends AbstractControllerTest {

@Rule
public TestName testMethodName = new TestName();

    @Before
    public void setUp() throws Exception
    {
           super.setUp();
        }
       @After
    public void tearDown() throws Exception
    {
        super.tearDown();
         }
 @Test
  public void myTestMethod ()
 {
    assertTrue("Response Validating",validate(baseEntity,perform()));
 }

}

有没有办法可以把方法 assertTrue("Response Validating",validate(baseEntity,perform()));在事务中可以与当前会话或新会话绑定,以便我的分离对象成为持久对象,然后我的应用程序也可以获得二级数据。我搜索了这个问题,并在链接上找到了解决方案:http://www.jroller.com/RickHigh/entry/hibernate_spring_simulating_an_opensessioninviewfilter 但此链接不符合我的要求,因为它需要在其上创建事务的目标对象。

【问题讨论】:

标签: java jsp servlets junit


【解决方案1】:
@Test
@Transactional
public void myTestMethod ()
{
       assertTrue("Response Validating",validate(baseEntity,perform()));
}

【讨论】:

  • 我不能在 myTestMethod 或类级别上使用@Transactional,因为如果我使用这个注解,那么在从服务器 Junit 获得响应后变得无响应(发生错误)因为如果我在这里使用这个注解它意味着上控制器类所在的级别事务,因此在这种情况下事务永远不会关闭,我必须重新启动我们的数据库。任何进一步的回应将不胜感激。
【解决方案2】:

@Transactional 注释myTestMethod(假设您使用的是基于注释的配置)。

【讨论】:

  • 我不能在 myTestMethod 或类级别上使用@Transactional,因为如果我使用这个注解,那么在从服务器 Junit 获得响应后变得无响应(发生错误)因为如果我在这里使用这个注解它意味着上控制器类所在的级别事务,因此在这种情况下事务永远不会关闭,我必须重新启动我们的数据库。任何进一步的回应将不胜感激。
  • 我无法理解您的评论。你是说你有冲突的事务管理运行?如果这样的事情可能会挂起您的数据库,那么您在某个地方存在严重的配置错误,需要与 DBA 交谈。
【解决方案3】:

我得到了这个问题的解决方案。我在我的测试代码中实现 OpenSessionInViewFilter 来解决这个问题,但是犯了一个愚蠢的错误。

请看下面的代码:

@Autowired
BeanFactory bf;

    @Before
        public void setUp() throws Exception
        {
             sessionFactory = (SessionFactory) bf.getBean("sessionFactory");
            Session session = SessionFactoryUtils.getSession(sessionFactory, true);
            session.setFlushMode(FlushMode.NEVER);
            TransactionSynchronizationManager.bindResource(sessionFactory, new SessionHolder(session));
    }

    @After
        public void tearDown() throws Exception
        {
            super.tearDown();
            SessionHolder sessionHolder = (SessionHolder) TransactionSynchronizationManager.unbindResource(sessionFactory);
            Session session = sessionHolder.getSession();
            SessionFactoryUtils.closeSession(session);

        } 

之前我没有使用 session.setFlushMode(FlushMode.NEVER)这是个错误。

顺便说一句谢谢

【讨论】:

    猜你喜欢
    • 2016-07-29
    • 2011-12-01
    • 2014-04-21
    • 2019-05-10
    • 2015-11-09
    • 2021-08-10
    • 1970-01-01
    • 2016-02-02
    • 2015-07-02
    相关资源
    最近更新 更多