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

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

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 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.

When to use Spring #Autowire annotation

Recently I had discussion with my friend regarding usage of Spring #Autowire annotation on entity(JPA) classes.
In our project we are using #Autowire annotaion to inject Entity but my friend suggesting not to use #Autowire annotaions on entity classes. When I asked why? He dont have the proper answer for that. So i just wanted to know are there any disadvantages using #Autowire annotaion on entity classes.
Also please explain when to go for #Autowire annotaion or not with example.
Thank in advance.
#Entity and #Autowire are not interchangeable.
#Entity annotation indicates that the JavaBean is a persistent entity.This is actually a JPA annotation and not a Spring Annotation.
#Entity will be used in the sessionFactory by the packagesToScan poroerty.
#Autowired: inject a resource by-type, i.e. by the class or by the interface of the annotated field or contractor. See my answer Inject and Resource and Autowired annotations
#Autowired is used to inject dependencies as an alternative to setting it via xml configurations
Maybe this answer will help you understand
Hibernate - spring annotated entities not scanned from within jar
UPDATE:
Following the comment bellow:
Company is your domain object, so you don't need to use spring in this case.
<bean id="company" class="xxx.Company"/>
The above will return the same instance with #autowire.
Even if you switch to scope="prototype" I don't see any reason to use spring for that.
You should have a service that will be used to CRUD company e.g.
CompanyService, this service will be a single tone so you will use #Autowire to inject it to the controller and it will use your JPA framework to implement CRUD's
To create a new company you will use:
Company c = new Company //this probably will be binded from your ui form
companyServic.saveOrUpdate(c);
See the following answer spring rest service - hibernate dao - annotations - pojo - namedqueries.
For common practice of DAO and services.
#Autowire is an annotation used to perform a dependency injection, its almost similar to the standard #Inject you can take a look at the spring reference manual to see the difference between those two annotations.
#Entity is a part of the jpa framework its used to mark a class as persistent, spring does not implement an equivalent annotation.

#PersistenceContext EntityManager thread-safety in Spring and Java EE

EntityManager is not thread-safe by definition.
Servlets specs says that in non-distributed environment and without implementing SingleThreadModel, there is only one servlet instance per definition.
Therefore, in Java EE when you inject an EntityManager through the #PersistenceContext into Servlet's field - it's not thread safe:
public class MyServlet extends HttpServlet {
// Not thread-safe, should be using EMF instead.
#PersistenceContext
private EntityManager em;
}
Is this correct to say that even though the default scope of Spring beans is singleton, the EntityManager is thread-safe as the Spring uses ThreadLocal to bind its transaction and EntityManager to it?
Is the above Servlets example still valid in Spring? Is it still not thread-safe?
Does the ThreadLocal approach works only for Spring managed beans and plain servlet is not one of those?
As far as I remember, it's the container responsibility to inject the EntityManager. In Glassfish Java EE implementation, it was the application server who discovers the #PersistenceContext as injection point.
How does it look like in Spring? Is the Spring Framework responsible for discovering those annotations or it's responsibility of the JPA implementor?
Question 2, 3, and 4 -- Spring does not pay attention to any class that is not a Spring Bean. Therefor Spring does not pay attention to you MyServlet class.
Therefore the answer for
2) is no
3) only Spring managed Beans
4) it is Springs responsibility, because Spring is the Container
For Question 1). It works this way, so the usage of an Spring Injected Entity Manager is effective thread save.

Resources