Spring boot EntityManager injection - spring-boot

In Java SE I can create EntityManager instance via EntityManagerFactory and I can create as many as I want.
In Spring boot I inject EntityManager via #PersistenceContext.
How does it work?
Does it mean in is injected only one time only? and what if I close it (like closing a session in hibernate?) how can I re-inject it? (like opening new session or creating new entityManager instance)

Related

Spring boot create many entity manager

In a spring boot application, when i start it, i see 68 times this line:
tor$SharedEntityManagerInvocationHandler [main] - Creating new EntityManager for shared EntityManager invocation
I have 8 jpa entity.
any reason to have so many entity manager created?
Edit
spring.jpa.open-in-view=false
spring.jpa.properties.hibernate.enable_lazy_load_no_trans=false
spring.datasource.url=jdbc:oracle:thin:#localhost:1521/cnn
spring.datasource.username=cnn
spring.datasource.password=test
spring.datasource.driver-class-name=oracle.jdbc.OracleDriver
spring.datasource.hikari.connection-timeout=60000
spring.datasource.hikari.maximum-pool-size=5
spring.jpa.show-sql=true
spring.jpa.properties.hibernate.show_sql=true
spring.jpa.properties.hibernate.format_sql=true
spring.jpa.generate-ddl=false
spring.jpa.hibernate.ddl-auto=validate
spring.jpa.hibernate.use-new-id-generator-mappings=true
2
Container managed entity managers are automatically propagated with the current JTA transaction and EntityManager references that are mapped to the same persistence unit provide access to the persistence context within that transaction. So it's not good practice to share an entity manager from a singleton, apart from concurrency problems, it would result in using the same transaction context for every method you call on your beans.
A simple solution to your need is to inject EntityManagerFactory references in your beans and create EntityManager objects calling the createEntityManager() method. The drawback is that you should manage transactions manually, no more relying on the container.
Otherwise another approach could be inject all of your entity managers in a main enterprise bean and implement business logic in service beans with methods to which you pass the appropriate managers

Spring-boot default EntityManager

Does spring-boot have a default EntityManager. I am setting one up right now but I noticed when my project loads I see this:
LocalContainerEntityManagerFactoryBean : Building JPA container EntityManagerFactory for persistence unit 'default'
Is this a default EntityManager and if so, how do I access it?
Thank you in advance.
You can use the #PersistenceContext annotation to inject the entity manager into your spring beans:
#PersistenceContext
EntityManager em;
When using spring-boot-starter-data-jpa, all you need to do is configure the data source using the spring.datasource.{url, username, password, driver-class-name} properties in application.properties.
If you want to use an in-memory database like H2 for development, not even that is necessary. Just include the database as a dependency.
Once you do that, you should be able to inject the EntityManager into your beans.

why `EntityManager` work,but EntityManagerFactory did not work for me?

I try to use Spring+JPA+Hibernate and try to inject EntityManagerFactory,and later create EntityManger in my code.But when I use entityManager.persist(user),the user not saving to the database.But when I try to inject the EntityManager instead of EntityManagerFactory,it worked !,I do not know where is the problem.
you can also see this question for more code.
When using a plain EntityManagerFactory instead of an EntityManager you need to call createEntityManager. This will always create a new EntityManager, this is basically a plain EntityManager not managed nor detected by Spring. So you will also have to start/commit transactions yourself.
When using the EntityManager you will obtain a transactional synchronized instance, which is managed by Spring and bound to the current transaction. So no need to start / commit a transaction yourself.
See also the JPA section of the reference guide.

Best practice for open/get Hibernate session in Spring 4 + Hibernate 4.3.1.final

In our project we use Spring and Spring Data (for server side API service), but sometimes we do query not using Spring Data, but using JPA criteria. In order to do so we use:
#PersistenceContext
private EntityManager em;
...
CriteriaBuilder cb = em.getCriteriaBuilder();
...
From the Spring docs:
Although EntityManagerFactory instances are thread-safe, EntityManager instances are not. The injected JPA EntityManager behaves like an EntityManager fetched from an application server's JNDI environment, as defined by the JPA specification. It delegates all calls to the current transactional EntityManager, if any; otherwise, it falls back to a newly created EntityManager per operation, in effect making its usage thread-safe.
So it seems that the way we use should get the current session if exists and if not should create new one. The issue we are facing is a memory leak of this use. seems like this way opens a lot of Hibernate session and does not close them.
So for the question: What is the best practice to getCurrent/open new session in Spring with Hibernate?
Note: HibernateUtil does not have getSessionFactory() as suggested in some other posts
Thanks,
Alon

Transaction in Spring with datasources create in runtime

I have a problem with transaction in spring, because in my project datasources are created in runtime from side files and according to documentation:
I should inject to TransactionManager dataSource and made it visible for annotation #Transactional using <tx:annotation-driven transaction-manager="txManager"/>.
So my question is how can I do it when I want to use annotation?
First of all how are you creating the datasources at runtime.
if directly as Datasource=new datasource... I will suges use BeanDefinitionBuilder in Spring 3.2 to Create the Datasourcebean and then register it via BeanDefinitionRegistry.
and then get the bean from Spring context and it will be considered using the transaction.

Resources