Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

java.lang.IllegalStateException: No transactional EntityManager available

Tags:

Project use Hibernate (JPA), Spring and Maven. My entity and DAO in a separate JAR.

pom.xml:

<project ...>     ...     <artifactId>database</artifactId>      <dependencies>         <dependency>             <groupId>org.hibernate</groupId>             <artifactId>hibernate-entitymanager</artifactId>             <version>3.5.4-Final</version>         </dependency>     </dependencies>     </project> 

DAO:

public class AbstractDAO<T extends BaseEntity> implements GenericDAO<T> {       private final Class<T> persistentClass;      private EntityManager entityManager;      public AbstractDAO(Class<T> entityClass) {         super();         this.persistentClass = entityClass;     }      @PersistenceContext     public void setEntityManager(EntityManager entityManager) {         this.entityManager = entityManager;     }       public EntityManager getEntityManager() {         return entityManager;     }      ...      public void fooBar() {        //Exception from this line        Session session = getEntityManager().unwrap(Session.class);        ...     }      .... 

}

I have a module, which use Spring.

pom.xml:

<project ...> ... <artifactId>api</artifactId>  <dependencies>     <dependency>         <groupId>org.springframework</groupId>         <artifactId>spring-core</artifactId>         <version>${spring.version}</version>     </dependency>      <dependency>         <groupId>org.springframework</groupId>         <artifactId>spring-context</artifactId>         <version>${spring.version}</version>     </dependency>      <dependency>         <groupId>org.springframework</groupId>         <artifactId>spring-orm</artifactId>         <version>${spring.version}</version>     </dependency>     .... </dependencies>   ...     </project> 

AppContext.xml:

<bean id="authService" scope="singleton" class="com.test.management.AuthServiceImpl" />      <bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean" name="EntityManagerFactory">         <property name="persistenceUnitName" value="default"></property>         <property name="dataSource" ref="dataSource"></property>         <property name="jpaVendorAdapter">             <bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">                 <property name="showSql" value="true" />                 <property name="generateDdl" value="true" />                 <property name="databasePlatform" value="${db.dialect}" />             </bean>         </property>          </bean>      <!-- Values are defined in db.properties -->     <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">         <property name="driverClassName" value="${db.driver}" />         <property name="url" value="${db.url}" />         <property name="username" value="${db.username}" />         <property name="password" value="${db.password}" />     </bean>      <bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager" name="TransactionManager">         <property name="entityManagerFactory" ref="entityManagerFactory"></property>     </bean>      <tx:annotation-driven />      <bean id="userDAO" scope="singleton" class="com.test.database.dao.impl.UserDAOImpl">     </bean>       <bean class="org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor" />  </beans>  

Service:

public class AuthServiceImpl implements AuthService {      @Autowired     private UserDAO userDAO;       @Override     public void authorization() {         userDAO.fooBar();      } } 

When I'm trying to get the session from EntityManager, I catch this exception:

java.lang.IllegalStateException: No transactional EntityManager available     at org.springframework.orm.jpa.SharedEntityManagerCreator$SharedEntityManagerInvocationHandler.invoke(SharedEntityManagerCreator.java:223)     at $Proxy121.unwrap(Unknown Source)  
like image 293
Anton Tsivarev Avatar asked Jan 25 '13 13:01

Anton Tsivarev


1 Answers

You must surround the method with the @Transactional annotation:

@Transactional public void fooBar() {    //Exception from this line    Session session = getEntityManager().unwrap(Session.class);    ... } 

And enable the spring @Transactional processing with the following declaration in your spring's xml configuration file (txManager is the id of the your manager).

<tx:annotation-driven transaction-manager="txManager" /> 
like image 191
poussma Avatar answered Nov 20 '22 21:11

poussma