#PersistenceContext EntityManager thread-safety in Spring and Java EE - spring

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.

Related

IS Spring Context and Spring IOC container both are same and ApplicationContext is part of it?

I know what is application Context. It is an interface which provides spring beans.
All beans get initialized in Spring IOC containers.
But How all three are connected. Could you please explain.
Spring beans are the instances of classes that spring manages. You create classes and "mark" them to be spring managed (putting #Component, using #Bean in java configuration and so forth - there are many ways to tell spring that the instance of some particular class should be managed by spring)
When spring starts it creates an application context with is a registry of all beans it resolves.
Spring can inject one bean into another and its the way of spring to instantiate beans.
The principle of "providing dependencies by external container" as opposed to maintaining dependencies by class itself called Inversion of control, and spring implements this concept.
Update 1
There is no such a thing as "spring context" technically speaking
Spring IOC container is a framework that manages the beans (your classes) by means of providing a technical abstraction called application context (its a real interface in java with implementation inside the spring code).
In order to benefit from spring your Beans should have dependencies between them. In this case spring framework that implements IOC principle can "inject" (provide, resolve) dependencies between beans.
Here is an example:
#Component
class A {
}
#Component
class B {
#Autowired
private A a;
}
When spring container instantiates class B (creates the object : new B()) it "understands" that this instance (we call it bean because it's managed by spring) has a "dependency" on class A and since A is also managed by spring, it can "inject" (read put a value) into the property a of class B.
This is called an Inversion of Control. You, as a programmer do not have to instantiate property b by yourself, spring does it for you.

Can I inject an JPA EntityManager using CDI and #PersistenceContext, like with Spring?

In Spring, I can inject an javax.persistence.EntityManager
into a Spring bean using the annotation #javax.persistence.PersistenceContext, like this:
#Service
public class MyRepository {
#PersistenceContext
private EntityManager entityManager;
}
This is documented in the Spring docs in chapter 20.5.2 Implementing DAOs based on plain JPA.
Is there a way to do this using CDI (specifically, Weld) if I am not using a Java EE container?
In particular, is it possible to reuse the annotation #PersistenceContext for CDI (because existing code uses it with Spring) ?
As far as I understand: When using a Java EE container, the container will interpret the annotation and inject an EntityManager. Is that correct? And is there a way to get this to work using Weld, but without a Java EE container?
I tried to inject the class above into another class using Weld (in Tomcat, without Java EE). The injection takes place, so Weld correctly creates an instance of MyRepository, however the field MyRepository.entityManager is null, as if the annotation #PersistenceContext was ignored.
What is happening (or rather, not happening) here?
You can do it this way:
create Entity Manager Factory Producer
public class EntityManagerFactoryProducer {
#Produces
#ApplicationScoped
public EntityManagerFactory create() {
return Persistence.createEntityManagerFactory("PU");
}
public void destroy(#Disposes EntityManagerFactory factory) {
factory.close();
}
}
and create Entity Manager Producer
public class EntityManagerProducer {
#Inject
transient EntityManagerFactory emf;
#Produces
#RequestScoped
public EntityManager create() {
return emf.createEntityManager();
}
public void destroy(#Disposes EntityManager em) {
em.close();
}
}
then you can use dependency injection (CDI will create one em for each request)
#Inject
EntityManager entityManager;
You have to start the CDI context in your main method
public static void main(String[] args) throws IOException {
Weld weld = new Weld();
WeldContainer container = weld.initialize();
Application application = container.instance().select(Application.class).get();
application.run();
weld.shutdown();
}
ps. If you have more then one PU use #Qualifier
While MilkMaid's answer is a sound way to go, I would just add a few more behind-the-scenes hints.
Is there a way to do this using CDI (specifically, Weld) if I am not using a Java EE container?
Short answer - there is. Weld can allow for injection of next to any object you wish to have injectable, however you need to mind who owns/manages this object. In your case, it is EntityManager which is stuff from JPA, so guess what - JPA manages the lifecycle of such object. Therefore you need to create a "wrapper" (in reality its a proxy) for such object which will be handled by CDI/Weld. And that what you need producer for.
as if the annotation #PersistenceContext was ignored.
Indeed, it is ignored. Here is a simplification of what happens. Normally, that is in EE container, Weld would make the injection happen but the real magic behind that is not a Weld core code, but rather an integration on the EE server side (who adopts Weld SPI to handle such annotations and turn them into beans which it then injects).
Generally speaking, trying to handle 'EE stuff' outside of EE containers might get tricky as you come across a lot of integration which originally happens inside the container, but you now need to handle that yourself.
Technically one could probably make the #PersistenceContext annotation work, maybe by writing a CDI extension. However, that is a nasty hack rather than anything else - one would be bending the EE-only annotation for SE usage. I would advise against it, but if you still want to go that way, the idea would be to basically make CDI think the #PersistanceContext is yet another #Inject plus provide the producer. This would mean a LOT of manual work, there is no in-built mechanism in CDI to handle that for you - this is normally the EE server's responsibility.

EJB 3.0 , are thread safe?

Hy,
I am a newbie in EJB. Now I am studying the EJB 3.0 specification. If I have two different JSF managed beans like the next ones:
#ManagedBean
public class CocheBean {
#EJB
private ICochesService cochesService = null;
}
#ManagedBean
public class UsuarioBean {
#EJB
private ICochesService cochesService = null;
}
The injecteds implementations for cochesService are the same in both cases?, I mean, for each annotation, the ejb container gets back a new object or is the same object?
Why do they refer to EJBs as session beans? Are they session scoped? Do they exist till the session of a user expires?
Its said that you dont have to worry if the stateless EJB are thread safe because the container has a pool of different instances for each request but if they are stateless and there is no danger that multiple threads access to just one ejb, why the container creates a pool of them and not just one?
Using JSF managed beans, if this bean is request or session scoped and because we inject the ejbs in this beans, they cannot be called more than once per user or per request at the same time, right?
How to specify the transactional atributes to EJB bean methods, with JPA annotations?
Thanks
This depends - if ICochesService is stateless than each of them will have different object. If it's stateful or singleton than both beans will have the same object injected
Answer to both questions is no :) See the Oracle docs
Exactly
You can call as many beans as you want per each request.
See the Oracle tutorial for Java Transaction API.

How to inject service in JSF managed bean without using Spring IOC

Typically if I have to inject a service in Spring I use
<bean id="mycontroller" class="com.MyController">
<property name="myService" ref="myService" />
and
<bean id="myService" class="com.MyService"></bean>
How to do the same when using JSF? I dont want to use two IOC containers for the beans and rather keep it in faces context itself. I have seen links such as
JSF 2 inject Spring bean/service with #ManagedProperty and no xml
and A problem about injecting spring bean into jsf bean . They talk about injecting Spring managed bean into JSF context.
What I am trying to do must be really simple but am not able to find any relevant info. Am a newbie and will appreciate any help.
I think you may be confused by the word "bean".
The thing is, the "service" you are talking about is also a Spring bean, right?
You probably have it as a service cause it has some additional features (probably transaction management) added by Spring, according to your configuration.
The JSF IoC container is very simplistic, it does not allow you to configure its lifecycle to include transaction management, AOP and things like that. Those things you have to do with Spring (or EJB, in a Java EE environment).
So, when using JSF with Spring, you usually have two choices:
Either you put the backing beans for the JSF pages in the JSF container, annotating them with #ManagedBean, #RequestScoped, #ViewScoped, etc; and injecting any necessary Spring bean with #ManagedProperty in a property (a setter is required)
Or skip the JSF container and put the backing beans along with all others in the Spring container, and use the Spring scopes of request/session, annotating them with Spring's annotations #Component, #Scope("request"), #Scope("session") and injecting with #Autowired, #Qualifier and the like.
Personally, faced with that choice I'd go with the first choice, cause it gives you #ViewScoped and some other niceties. It's true it makes use of two IoC containers but then, which Java EE app does not?
If you want to go the second route anyway, you may also add a view scope for Spring beans, backed by JSF viewMap.
What Spring calls a "Service" is in Java EE terms an "EJB". EJB is out the box available in Java EE web profile containers like Glassfish, JBossAS and TomEE.
To create a stateless EJB service, just use #Stateless on the class:
#Stateless
public class SomeService {
public void doSomething() {
// ...
}
}
And to inject it in a JSF managed bean, just use #EJB on the property-to-be-injected:
#ManagedBean
#ViewScoped
public class SomeController {
#EJB
private SomeService service;
}
That's it. No getter/setter necessary. No XML boilerplate necessary.

Using JdbcTemplate with a "Non-Spring-Bean" JNDI DataSource

Page 342 of spring-framework-reference.pdf (bundled with spring-framework-3.1.0.M2) states, "The JdbcTemplate can be used within a DAO implementation through direct instantiation with a DataSource reference." However, it goes on to say, "The DataSource should always be configured as a bean in the Spring IoC container."
Does anyone know why the DataSource shouldn't be provided to a JdbcTemplate from a plain-old JNDI lookup outside of the Spring container, e.g. How to programatically use Spring's JdbcTemplate?
"The DataSource should always be configured as a bean in the Spring IoC container."
It appears that this note is intended to clarify the preceding statement:
"The JdbcTemplate can be used within a DAO implementation through direct instantiation with a DataSource reference, or be configured in a Spring IoC container and given to DAOs as a bean reference."
I believe the information these statements are trying to convey is that when you're configuring a DAO in Spring, you can either:
inject the DataSource directly into the DAO and create the JdbcTemplate in code yourself, or
you can make the JdbcTemplate a Spring bean as well, inject the DataSource into the JdbcTemplate, and inject the JdbcTemplate into the DAO.
The note, then, means that if Spring is managing the DAO and its dependencies, the DataSource must be a Spring bean in either case, as it needs to be injected either into the DataSource for use in constructing the JdbcTemplate (case 1) or into the JdbcTemplate itself (case 2).
I wouldn't take it to mean that a DataSource used in a JdbcTemplate must always be managed by Spring and only Spring. The note does give that impression. It's probably worth filing a bug against.

Resources