java.lang.IllegalStateException: No transactional EntityManager available
62,089
Solution 1
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" />
Solution 2
Try this ?
entityManager=entityManager.getEntityManagerFactory().createEntityManager();
Session session = (Session) entityManager.unwrap(Session.class);
Solution 3
None of this was working for me, I finally found that the issue was that I was making my method @Transactional instead I needed the class to be @Transactional
Related videos on Youtube
Author by
Anthony Tsivarev
Updated on July 13, 2022Comments
-
Anthony Tsivarev almost 2 years
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)
-
eis over 11 yearsso.. what kind of entity manager you expect to be available?
-
Anthony Tsivarev over 11 yearsSorry, I described in detail the question. What do you mean? Unfortunately, I'm new to Hibernate.
-
eis over 11 yearsOk, thank you for the added information. Are you within a transaction when you call the method, getting the exception?
-
Anthony Tsivarev over 11 yearsWell... I thought that working with a transaction is in automatic mode, because i use
<tx:annotation-driven />
-
eis over 11 yearsit says it's annotation driven, you'll need to provide annotations to places that you need to be transactional. I don't see
@Transactional
annotations in your code.
-
-
poussma almost 11 yearsi have added the piece of spring configuration
-
daydreamer almost 10 yearsThis works for me, what is the magic behind it? why
@PersistenceContext EntityManager entityManager
is notTransactional
butentityManager.getEntityManagerFactory().createEntityManager();
is? -
baybora.oren almost 10 yearsShortly for my understanding; @PersistenceContext : is for application server usage (without transaction control if nothing configured). If you want it transactional you can add @Transactional annotation to make spring wrap it. createEntityManager : is for application control by spring) spring will make entityManager transactional (inject).
-
VB_ over 9 years@baybora.oren do you mean
@Transactional @PersistenceContext private EntityManager entityManager
? That's not allowed -
VB_ over 9 years@baybora.oren look at stackoverflow.com/questions/27570641/… please
-
baybora.oren over 9 years@V_B
@PersistenceContext private EntityManager entityManager;
we cant use@Transactional
because of before transactional proxy created we create entity manager. -
Shafin Mahmud about 7 years@baybora what I actually understand, Here
entityManager
is being created explicitly, that is actually Application Managed Entity Managers . Container like Spring is not resposible for maintaing the life cycle for theEntityManager
created from it. But you can@Autowire
EntityManagerFactory
directly as the bean is already configured in theapplicationContext
. Hence this could be simple like thisemf.createEntityManager().unwrap(Session.class)' to get
Session` -
djangofan over 6 yearsI added that annotation to my Test method, and it works although i dont understand why.
-
Mohammadreza Khatami over 5 yearsI got this exception cause of session.beginTrasaction() beside @Transactional which was a mistake!
-
royatirek over 3 yearsIt leaks connections. I have tested this code. We need to manage it manually.