init 方法中的 getResultList() 给出错误“会话已关闭”

发布于 2024-12-10 12:19:02 字数 1723 浏览 0 评论 0原文

我试图在服务类的 init 方法中从数据库加载一些数据,但是当我调用“getResultList()”方法时,它会抛出异常“会话已关闭”。

我的 applicationContext.xml

<bean class="org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor" />    
<bean id="testService" class="com.impl.TestServiceImpl" init-method="init" />
<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
    <property name="entityManagerFactory" ref="entityManagerFactory" />
</bean>
<tx:annotation-driven transaction-manager="transactionManager" />

我的服务类:

public Class TestServiceImpl implements TestService {
private EntityManager entityManager;

@PersistenceContext
public void setEntityManager(EntityManager entityManager) {
   this.entityManager = entityManager;
}   

public void init() {
    Query query = entityManager.createQuery("from myTable");
    query.getResultList();  // this causes error...
}
}

这是错误消息:

SEVERE: Exception sending context initialized event to listener instance of class 
org.springframework.web.context.ContextLoaderListener
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 
'testService' defined in ServletContext resource [/WEB-INF/applicationContext.xml]: 
Invocation of init method failed; nested exception is
javax.persistence.PersistenceException: org.hibernate.SessionException: Session is 
closed!
Caused by: javax.persistence.PersistenceException: org.hibernate.SessionException: 
Session is closed!
at 
org.hibernate.ejb.AbstractEntityManagerImpl.throwPersistenceException(AbstractEntityManagerImpl.java:630)

那么我在这里做错了什么?我该如何解决这个问题?谢谢。

I am trying to load some data from DB in the init method of my service class but when I call the "getResultList()" method then it throws an Exception "Session is closed".

my applicationContext.xml

<bean class="org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor" />    
<bean id="testService" class="com.impl.TestServiceImpl" init-method="init" />
<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
    <property name="entityManagerFactory" ref="entityManagerFactory" />
</bean>
<tx:annotation-driven transaction-manager="transactionManager" />

my service class:

public Class TestServiceImpl implements TestService {
private EntityManager entityManager;

@PersistenceContext
public void setEntityManager(EntityManager entityManager) {
   this.entityManager = entityManager;
}   

public void init() {
    Query query = entityManager.createQuery("from myTable");
    query.getResultList();  // this causes error...
}
}

This is the error message:

SEVERE: Exception sending context initialized event to listener instance of class 
org.springframework.web.context.ContextLoaderListener
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 
'testService' defined in ServletContext resource [/WEB-INF/applicationContext.xml]: 
Invocation of init method failed; nested exception is
javax.persistence.PersistenceException: org.hibernate.SessionException: Session is 
closed!
Caused by: javax.persistence.PersistenceException: org.hibernate.SessionException: 
Session is closed!
at 
org.hibernate.ejb.AbstractEntityManagerImpl.throwPersistenceException(AbstractEntityManagerImpl.java:630)

So what I am doing wrong here? How can I solve this issue? Thanks.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

你的笑 2024-12-17 12:19:02

首先,您的 TestServiceImpl 没有用 @Transactional 注释,但即使是,它也不会工作,请参阅:事务性初始化方法SPR-2740 - 这解释了这是设计使然。

您可以做的是仅使用 init() 方法来调用其他 bean 的业务方法,该方法被标记为 @Transactional

private TestDao testDao;

public void init() {
  testDao.findAll();
}

TestDao bean 中:

private EntityManager entityManager;

@Transactional
public findAll() {
  Query query = entityManager.createQuery("from myTable");
  return query.getResultList();
}

First of all your TestServiceImpl is not annotated with @Transactional, but even if it was, it wouldn't work, see: Transactional init-method and SPR-2740 - which explains this is by design.

What you can do is to use init() method only to call some other bean's business method, which is marked @Transactional.

private TestDao testDao;

public void init() {
  testDao.findAll();
}

And in TestDao bean:

private EntityManager entityManager;

@Transactional
public findAll() {
  Query query = entityManager.createQuery("from myTable");
  return query.getResultList();
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文