I have a Spring MVC 4.0 application, and I am learning JPA. I use Hibernate as the JPA implementation.
I can configure Hibernate as described in this tutorial. It works fine, but I have to use Hibernate's Session
object:
@Autowired
SessionFactory sessionFactory;
...
Session session = sessionFactory.openSession();
Now, I want to use JPA's EntityManager
instead. I have followed this tutorial on the same web site (the configuration is very similar). And I tried to obtain an EntityManager
object this way:
@PersistenceContext
EntityManager entityManager;
I got a runtime message:
java.lang.IllegalStateException: No transactional EntityManager available
Then, I followed the suggestion in this answer, and tried to use the following code:
@PersistenceContext
EntityManager entityManager;
...
entityManager=entityManager.getEntityManagerFactory().createEntityManager();
It works a few times (about 9 repetitive method invocations), and then the application freezes.
What is the right way to get EntityManager
in Spring + Hibernate configuration?
I do not need any Spring transaction functionality for now. I just want to get an access to EntityManager
and play with JPA.
Spring/Hibernate configuration file (hibernate.xml)
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.0.xsd">
<bean id="dataSource" class="org.apache.tomcat.dbcp.dbcp.BasicDataSource">
<property name="driverClassName" value="com.mysql.jdbc.Driver" />
<property name="url" value="jdbc:mysql://localhost:3306/test_db" />
<property name="username" value="test" />
<property name="password" value="test" />
</bean>
<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="packagesToScan" value="net.myproject" />
<property name="jpaVendorAdapter">
<bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter" />
</property>
<property name="jpaProperties">
<props>
<prop key="hibernate.hbm2ddl.auto">update</prop>
<prop key="hibernate.dialect">org.hibernate.dialect.MySQL5Dialect</prop>
<prop key="hibernate.show_sql">true</prop>
</props>
</property>
</bean>
<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="entityManagerFactory" />
</bean>
<bean id="persistenceExceptionTranslationPostProcessor" class="org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor" />
<tx:annotation-driven />
</beans>
The class where I attempt to use EntityManager
@Repository
public class ProductsService {
@PersistenceContext
EntityManager entityManager;
@Transactional
public GridResponse<Product> getProducts(GridRequest dRequest) {
// The following line causes the exception: "java.lang.IllegalStateException: No transactional EntityManager available"
Session session = entityManager.unwrap(Session.class);
//...
}
...
The complete example of getting EntityManager using the custom configuration in Spring Boot. Open eclipse and create maven project, Don't forget to check 'Create a simple project (skip)'click on next. Fill all details(GroupId – entitymanager, ArtifactId – entitymanager and name – entitymanager) and click on finish.
We don't have direct access to the EntityManager in a JpaRepository. Therefore, we need to create our own. Likewise, we can use the @PersistenceUnit annotation, in which case we'll access the EntityManagerFactory and, from it, the EntityManager.
In a Spring Boot application that uses Spring Data JPA, you can inject an instance of EntityManager in your repository/service/controller class. The Spring’s IoC container manages an EntityManager bean, and concrete implementation is provided by Hibernate framework.
Hibernate EntityManager or, also called JPA EntityManager has an important aspect of connecting with the database of a program. One of the most expensive transactions is considered to be the Database connection.
Now you can run the main program to let Hibernate create the corresponding table in the database, as we specified the property spring.jpa.hibernate.ddl-auto=update in the Spring application configuration file. 4. Inject an EntityManager object
With Spring Data JPA, you can inject an EntityManager object in a repository, service or controller class - depending on your need. Create the ContactRepository class and use @Autowired annotation to inject an EntityManager instance as follows: At runtime, Spring Data JPA will initialize JPA EntityManagerFactory for persistence unit ‘default’.
For the @PersistenceContext EntityManager entityManager;
approach, add tx:annotation-driven
to your .xml configuration and mark your methods where you use entityManager
as @Transactional
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With