Question

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.

Was it helpful?

Solution

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();
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top