Meaning of #PersistenceContext in JSF 1.2 Managed Beans - java

JSF 1.2 specification allows injection of an entity manager into a managed bean via the #PersistenceContext annotation (JSR 252, p. 5-13).
What is the semantics of such an entity manager regarding transactions and lifecycle?
Is an EAR-scoped JTA-style persistence unit supposed to work here?

#Stateless
public class YourServiceBean implements YourService {
#PersistenceContext(unitName="YourServicePU")
EntityManager em;
// ...
}
This will inject an EntityManager instance that you do not have to dispose of (the container takes care of it) and is supposed to play nice with container-managed transactions.

Related

Spring transactions, EntityManager lifecycle

I am developing a project with spring framework.
I have following architecture: all database code is in dao classes, all application logic is in service classes, http requests are processed using spring mvc rest controllers.
#Repository
public class UserDao {
#PersistenceContext
private EntityManager em;
public void editUser(User user) {
...
}
}
#Service
public class UserService {
#Autowired
private UserDao userDao;
#Transactional
public void editUser(User user) {
...
}
}
#RestController
#RequestMapping(value = "/UserCtrl", produces = "application/json;charset=UTF-8")
public class UserCtrl {
private static final Logger logger = LogManager.getLogger(AppConfig.LOGGER_NAME);
#Autowired
private ApplicationContext appContext;
#RequestMapping(value = "/editUser")
public ActionResult editUser(#ModelAttribute User user) {
ActionResult rslt = new ActionResult();
try {
UserService userService = appContext.getBean(UserService.class);
userService.editUser(user);
rslt.setSuccess(true);
} catch (Exception ex) {
logger.error("editUser", ex);
rslt.setSuccess(false);
}
return rslt;
}
}
This code works correctly.
One thing I cannot understand is how aop proxy of UserService bean starts transaction, when EntityManager is injected only in UserDao class. Can somebody explain me how this works and how EntityManager lifecycle is managed by spring framework ?
Any help appreciated.
The TransactionManager is responsible for managing the transaction boundaries
in Spring Framework.
When you annotate the business method with #Transactional you are instrumenting the method with an aspect.
Before executing the method, this aspect interact with TransactionManager which decides if it is necessary to create a new Transaction or use a preexisting one. In the case of create a new Transaction, a new Entity Manager is created from EntityManagerFactory and is associated to the current thread alonside with the Transaction.
The EntityManager is responsible to iterate with the database. When you inject it with #PersistenceContext, Spring injects an proxy to the EntityManager.
Whenever an operation is executed in the EntityManager proxy it looks the EntityManager associated with the thread.
Based on the snippet of code you provide you are using spring with some implementation of JPA you are using J2EE container for your web application and bases on my guess I think this is good article about how things works.
Basic concepts :
EntityManager - A class that manages the persistent state(or lifecycle) of an entity.
Persistence Unit - is a named configuration of entity classes.
Persistence Context - is a managed set of entity instances. The entities classes are part of the Persistence Unit configurations.
Managed Entities - an entity instance is managed if it is part of a persistence context and that Entity Manager can act upon it.
Based on this article you use Container Managed EntityManager by using #PersistenceContext
When a container of the application(be it a Java EE container or any other custom container like Spring) manages the lifecycle of the Entity Manager, the Entity Manager is said to be Container Managed. The most common way of acquiring a Container Managed EntityManager is to use #PersistenceContext annotation on an EntityManager attribute.
And the injection is like this :
A Transaction Scoped Entity Manager is returned whenever a reference created by #PersistenceContext is resolved.
and
Every time an operation is invoked on an Entity Manager, the container proxy(the container creates a proxy around the entity manager while instantiating it ) checks for any existing Persistence Context on the JTA Transaction. If it finds one, the Entity Manager will use this Persistence Context. If it doesnt find one, then it will create a new Persistence Context and associates it with the transaction.
So the lifecycle of of entity manager is managed by your container and
we work with an instance of EntityManager, the only role of EntityManager is to determine the lifetime of the Persistence Context. It plays no role in dictating how a Persistence Context should behave. To reiterate, Persistence Context is a managed set of Entity instances. Whenever a transaction begins, a Persistence Context instance gets associated with it. And when a Transaction ends(commits for example), the Persistence Context is flushed and get disassociated with the transaction.
In the nutshell container instantiate your EntityManager by the EntityManagerFactory you provide and manage it's lifecycle but inject the proxy of EntityManager for you. The TransactionManager is responsible for creating, commiting and ... tranactions based on annotations you provide ,whenever it begins the transaction the PersistancecContext associated with it and when the tranasction ends it commites the state of PersistenceContext. The EntityManager works with PersistenceContext and if it's not provided the EntityManager creates one. The EntityManager is threadsafe as long as it holds no state and the state (PersistenceContext) is attached to current tranasction.
Hope this helps.

Migrating CDI/EJB annotations to Spring annotations

I'm trying to replace my CDI/EJB annotations with Spring ones. But I'm struggeling how to do it right.
This is what I have in CDI/EJB:
#Stateless
#TransactionAttribute(TransactionAttributeType.REQUIRES_NEW)
class Service {
#Inject
EntityManager em;
}
#Named
#RequestScoped
class Facade {
#Inject
Service service;
}
Now I would do the following:
#Stateless
#Transactional
#Repository
class Service {
#Inject
EntityManager em;
}
What about the stateless? What is the aquivalent in spring?
Obvious I cannot just remove this annotation, bc then I'm getting these exception:
javax.el.PropertyNotFoundException: /input.xhtml #15,30 registerButtonAction="#{facade.createNew()}": The class 'Facade$Proxy$_$$_WeldClientProxy' does not have the property ...
Further:
#Named
#Service
class Facade {
#Autowired
Service service;
}
Do I have to simply replace all #Inject annotations with #Autowired?
Is there something in Spring that takes care of EL naming, so that I can remove the #Named?
Do I have to annotate my JPA entities too?
Stateless and Stateful Beans are EJB concepts, but Spring offers similar services through Service Beans. Put the #Service annotation in your Business Logic classes, and if you want your beans to be "Stateless" or "Stateful" just configure your bean scope (like Request or Session).
Spring also has a built-in transaction management API, so your Transaction annotations may need to be changed.
Finally, Spring is compatible with many persistence frameworks including JPA. IF you want to keep JPA it is OK, and feel free to change it for another technology if you desire (maybe Hibernate, or MyBatis)
The stateless and stateful concepts are EJB; Spring doesn't have such a notion. Spring uses POJOs, without any support for stateful beans. You're on your own there.
Spring uses javax.annotation.Resource annotation; I'd prefer that to #Autowired.
Spring supports #Inject and #Named directly. No need to use #Autowired and #Component (Spring's equivalents) if you don't want to. No need to bring in #Resource either.
// This is a singleton by default, which is OK since you previously
// had it marked as stateless
#Named
#Transactional(propagation=Propagation.REQUIRES_NEW)
class Service {
#PersistenceContext // Use JPA's usual annotation
EntityManager em;
}
// You may not still need this, but if you do ...
#Named
#Scope("request")
class Facade {
#Inject
Service service;
}

CDI #TransactionAttribute for bean

I am experimenting with CDI on a test application. I have a DAO which injects a container managed JTA persistence context like this:
public class TestDAO implements Serializable {
#PersistenceContext
private EntityManager entityManager;
public void insertEntity(Test test) {
entityManager.persist(test);
}
}
Now I have a CDI controller bean like this:
#Named
#SessionScoped
public class TestController implements Serializable {
#Inject
private TestDAO testDAO;
public void finishGame() {
testDAO.insertEntity(new Test(1, 2, 3));
}
}
If I run this, I receive an error in the DAO when trying to insert the entity, because there is no active transaction available. So far so good. I can solve this by making the controller bean a stateful EJB which will wrap the finishGame() in a transaction.
But let assume I don't want an EJB. As a test I annotated the finishGame() with the #TransactionAttribute annotation and it worked(the controller bean is NOT an EJB). So my question is: how does it work? Does the CDI define #TransactionAttribute for plain beans? I know that Seam Persistence Module does this, but I am not using it. Actually I added it to the project, but I removed it after, because I received awkward exceptions.
Could anyone clear my confusion? Do really CDI define #TransactionAttribute for plain beans?
P.S. I have another sort of question. I see the tendencies is to port all EJB annotations to plain beans. So will EJBs become obsolete in the future? I mean I saw in JIRA that #TransactionAttribute will be added in the future for plain beans(the task is still not resolved). So isn't this eclipsing EJBs, sort of duplicating functionality?
Best regards,
Petar
You need do define a transaction interceptor. Basically define a #Transactional annotation and intercept all methods annotated with it. In the interceptor just begin, commit or rollback the transaction. It gets more complicated when transaction propagation comes into the picture. So check if Seam doesn't have anything ready-to-use http://seamframework.org/Seam3/PersistenceModule

EntityManager became NULL after a while (about 10m)

in my JavaEE 6 application (JBoss 6.0.0.Final) I have a class hierarchy outlined like this
#Stateful public class UserFacade
{
#Inject #MyRepository
private EntityManager em;
}
#Stateful public class UserBl
{
#EJB private UserFacade fUser;
}
public class MyServlet
{
#EJB private UserBl blUser;
}
The servlet is used during a login process and it works fine. But if the servlet is called from the same browser after an inactivity period of about 10 minutes, the EntityManager em in UserBl became NULL (checked this explicitly before using it).
In a other application (JBoss 5.1.0.GA) I've had a similar issued and solved it by explicitly checking for NULL and looking up the EntitiyManager from the context in that case.
I'm wondering if there is a fundamental design flaw or if I missed something. In this scenario #Stateless Beans are possible, too. But in my understanding this should also work with #Stateful Beans.
As far as I recall, injection of stateful beans has been problematic (at least in JavaEE 5). It might be a passivation-activation issue.
But you don't really need stateful beans here - the EntityManager is per-transaction (by default; you can set it to extended which allows it span multiple requests) and a stateless bean is the proper way to go.

How is threadsafty guranteed with #PersistenceContext?

According to many examples it is possible to inject an EntityManager into #Stateless or #Singleton EJBs like this:
#Stateless // or #Singleton
public class MyRepository {
#PersistenceContext
private EntityManager em;
...
}
The EJB 3.1 Spec says that dependency injection is only performed at construction time, so that all callers of MyRepository would use the same instance of EntityManager. How does the EJB container ensure that the correct EntityManager instance is used?
My understanding is that a #Stateless bean will never be used by two clients concurrently; the container will simply create more instances of the same bean if it needs to serve multiple clients.
As for #Singleton beans, the spec says that by default they use Container Managed Concurrency, where the container uses method Locks and could reject clients with a timeout exception if the singleton is busy.
Edit: additionally, the #PersistentContext type is transaction-scoped by default (16.11.1.1 in the spec) so all entities managed by EntityManager are detached at the end of each transaction.

Categories

Resources