Spring-boot default EntityManager - spring-boot

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.

Related

What is the difference between annotating EntityManager with #Autowired and #PersistenceContext? Which one should be preferred?

I am developing a Spring-Boot application using spring-boot-starter-data-jpa. I am not able to understand which annotation I should use for injecting EntityManager?
#Autowired or #PersistenceContext
I know #PersistenceContext is a JPA annotation whereas #Autowired belongs to Spring. But internally how do they make a difference?
I have already taken a look at this. But could not understand the exact reason.
A datasource is source of data. This could be for example a database.
One option if you need multiple datasources is to define them in a persistence.xml file. Here you can define multiple and separate them by name.
#PersistenceContext will then give you more fine grain of what you want to inject. Here you can select which datasource by defined name. There are some other options too.
https://docs.oracle.com/javaee/7/api/javax/persistence/PersistenceContext.html
If using #Autowire you are just injecting the available persistence context by bean name. If you have 2 or more persistence contexts this may fail because of ambiguity.

Spring boot EntityManager injection

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)

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.

Using Spring+Hibernate for testing purposes

I want to clarify my problem a bit more:
I understand the purposes of using SPring Framework (i.e. container-managed object lifecycle) and also Hibernate (using ORM between Javaobjects and relational database systems - impedance mismatch resolution).
I understand how we autowire an object and Spring takes over the creation and destruction of the object during runtime by looking at the applicationContext.xml file (in addition to persistence.xml file if using Hibernate or any other persistence provider).
What I want to do is the following:
I would like to implement my own shopping service. I already have entity (item) annotated with #Table, #Id, #Column, etc. to tell JPA that this is what will be stored in the database.
I already have a DAO interface (currently only add and delete methods) implemented by a DaoImpl class where I have done the following:
#Repository
#Transactional
public class MyShopDbDaoImpl implements MyShopDbDao {
// The following named unit will be in my persistence.xml file
// Which will be placed in src/main/resources/META-INF folder
#PersistenceContext(unitName="myShopDbDao")
private EntityManager em;
// Getters for em (simply returns em)
// Setters for em (simply assigns an em supplied in the args.)
// Other query method
}
I also have a ShopDbController controller class that uses:
#Autowired
// defined in the applicationContext.xml file
private MyShopDbDao myShopDbDaoImpl
What I am struggling with is the "Understanding" of EntityManagerFactory and EntityManager relationships along with how the transactions must be managed. I know that the following hierarchy is the main starting point to understand this:
Client talks to a controller.
Controller maps the request and gets the entitymanager to do queries and stuff to the database (either a test/local database with JUNIT test etc. or an actual SQL-type database).
What I do know is that transactions can be managed either manually (i.e. beginning, committing, and closing a session) or through Spring container (i.e. using bean defs in applicationContext.xml file). How can I get more information about the entitymanagers and entitymanagerfactory in order to setup my system?
I didn't find the online documentation from Oracle/Spring/Hibernate very helpful. I need an example and the explanation on the relationship between entitymanagerfactory, sessionfactory, entitymanager, and transactionmanager. Could someone please help me with this?
I don't need people to hold my hand, but just put me in a right direction. I have done Spring projects before, but never got to the bottom of some stuff. Any help is appreciated.
EntityManagerFactory will obtain java.sql.Connection objects, through opening/closing new physical connections to the database or using a connection pool (c3p0, bonecp, hikari or whatever implementation you like). After obtaining a Connection, it will use it to create a new EntityManager. The EntityManager can interact with your objects and your database using this Connection and can manage the transaction through calling EntityManager#getTransaction and then calling EntityTransaction#begin, EntityTransaction#commit and EntityTransaction#rollback that internally works with Connection#begin, Connection#commit and Connection#rollback respectively. This is plain vanilla JPA and Spring has nothing to do up to this point.
For transaction management, Spring helps you to avoid opening/closing the transactions manually by using a transaction manager, specifically a class called JpaTransactionManager. This transaction manager will make use of your EntityManagerFactory to open and close a transaction for the EntityManager created for a set of operations. This can be done either using XML configuration or #Transactional annotation on your classes/methods. When using this approach, you won't directly work with your specific classes anymore, instead Spring will create proxies for your classes using cglib and make use of the transaction manager class to open the transaction, call your specific method(s) and execute a commit or rollback at the end, depending on your configuration. Apart of this, Spring provides other configurations like read-only transactions (no data modification operation allowed).
Here's a basic configuration of the elements explained above using Spring/Hibernate/JPA:
<!--
Declare the datasource.
Look for your datasource provider like c3p0 or HikariCP.
Using most basic parameters. It's up to you to tune this config.
-->
<bean id="jpaDataSource"
class="..."
destroy-method="close"
driverClass="${app.jdbc.driverClassName}"
jdbcUrl="${app.jdbc.url}"
user="${app.jdbc.username}"
password="${app.jdbc.password}" />
<!--
Specify the ORM vendor. This is, the framework implementing JPA.
-->
<bean id="hibernateVendor"
class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter"
showSql="false"/>
<!--
Declare the JPA EntityManagerFactory.
Spring provides a class implementation for it.
-->
<bean id="entityManagerFactory"
class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean"
persistenceXmlLocation="classpath*:META-INF/persistence.xml"
persistenceUnitName="hibernatePersistenceUnit"
dataSource-ref="jpaDataSource"
jpaVendorAdapter-ref="hibernateVendor"/>
<!--
Declare a transaction manager.
Spring uses the transaction manager on top of EntityManagerFactory.
-->
<bean id="transactionManager"
class="org.springframework.orm.jpa.JpaTransactionManager"
entityManagerFactory-ref="entityManagerFactory"/>
From what i see, your em reference should be a functioning proxy object to your database (this EntityManager is the thing that should be a spring bean, having configured everything, like DB url, driver, etc. Apart from this none of your code should depend on what DB you have). You don't need to know about the classes you mention (entitymanagerfactory sessionfactory transactionmanager). Easy example is:
List<MyBean> bean = (List<MyBean>)em.createNamedQuery("select * from mydb").getResultList();
It should be this easy to run a select * query and get your MyBean typed objects straight ahead, without any explicit conversion by you (this is what hibernate is for).
Similar for insert:
em.persist(myBean);
where myBean is something annotated for Hibernate.
Briefly about transactions, i found best to annotate #Transactional on service METHODS (you did it on a whole dao).
To be very very general:
an entitymanagerfactory is an object responsible of the creation of the entitymanager and it comes from the JPA specifications.
SessionFactory is the hibernate implementation of entitymanagerfactory
session is the hibernate implementation of entitymanager
A transacation manager is an object who manages transaction when you want to define a transaction manually.
So if you want to use hibernate, use SessionFactory and session. And if you want you to stay "generic" use the EntityManagerFactory.
http://www.javabeat.net/jpa-entitymanager-vs-hibernate-sessionfactory/
http://www.theserverside.com/tip/How-to-get-the-Hibernate-Session-from-the-JPA-20-EntityManager

Is it possible to use #Transational worked in Spring, Eclipselink &Tomcat environment?

HiAll,
I was confused by the EclipseLink for Tomcat documentation saying:
Limitations to JPA:
No #PersistenceContext injection of a container managed persistence unit is available - use Persistence.createEntityManagerFactory(JTA_PU_NAME)
and, also by this question&answer:
but the typical JPA configuration in Spring looks like this, so you don't need to create EntityManager manually :
#PersistenceContext
private EntityManager em;
So, the question is: may I use this annotation #PersistenceContext for the entityManager to be sure that it will be created automatically and I dont need to create it manually?
Currently my #Transactional annotation does not work properly and I'm afraid it is because of creating the entity manager manually!
Please, need help.
EclipseLink documentation says that #PersistenceContext is not handled by Tomcat on its own. However, if you use Spring, #PersistenceContext is handled by Spring, so that you can use it.
See also:
13.5 JPA

Resources