JSF2: Open Session in View with EJBs? - java

Does it make sense to talk about the Open Session In View Pattern within JSF2 applications?
My app has JSF2 Managed Beans calling Business Service EJBs that do all the db-related stuff (there's a DAO layer but that doesn't matter right now).
Having OSIV pattern would mean that the Managed Bean would have to somehow make sure the underlying session was opened.
I am also using JPA.

Theoretically, the issue is exactly the same: entity will become detaches when they leave the EJB unless something keeps the scope of the EntityManager open. (Here is a great post about the topic in general: JPA implementation patterns: Lazy loading).
From a blog post I read:
8) No Open Entity Manager In View support.
[...] In EJB3, when your entity leaves bean
with transaction scoped EntityManager,
it is detached from persistence
context and you may no longer rely on
lazy loading (in fact, JPA
specification does not specify the
behavior in such situation, probably
some vendor dependent exception will
be thrown...) Of course, you may use
EntityManager with extended
persistence context, holding the
transaction and persistence context as
long as you want. But this feature is
only available for SFSB, while DAO
classes are typical examples of
stateless services, since they only
dispatch calls to the persistence
layer. Additionally, having dedicated
DAO bean instance for each client
seems to be a big overkill.
I'm however not sure it is really true. From my understanding you should be able to write a servlet filter which uses the UserTransaction to start and commit the transaction (like the regular filter in OSIV). EJB would then participate in the transaction started in the filter and the EntityManager would remain open. I haven't tested it though, but my suggestion would be to give it a try.

Related

Combining MDB, JPA and JTA

I'm developing a system to process messages and update the database accordingly, but I need to keep some degree of isolation between layers. I have in mind something like the following.
MyDao.java: a #Stateless bean that provides database access. MyDao accesses the database using JPA, with an EntityManager injected by #PersistenceContext.
MyMdb.java: an MDB that listens on a queue. MyMdb uses MyDao by injection with #EJB.
One single execution of MyMdb.onMessage() needs to perform several accesses to the database, both read and write.
On the one hand, this makes me think that a #Stateless bean is not the right choice for MyDao: the EntityManager instance in MyDao could be randomly accessed by different executions of MyMdb.onMessage(), leading threads to interfere with each other.
On the other hand, JPA documentation says that the injected EntityManager is just a proxy: the actual persistence context on which it operates is the one bound to the JTA transaction. This way everything should be ok because, even though EntityManagers are "shared", each MDB will have a different transaction ongoing and thus work in safe isolation.
What is the right scenario? Am I missing something?
Entity managers injected in a stateless EJB in the way that you described are exactly what you should do.
This type of injection provides a 'Container-Managed Entity Manager' which is 'transaction scoped'.
So in the scenario that you describe.
the onMessage MDB call will create a transaction
the call to the stateless bean will happen to the same transaction context, creating an Entity Manager which will live until the transaction finishes usually when the MDB method returns.
The specific type of injected entity manager for the same EJB instance doesn't survive and is not re-used across different transactions.

JTA & MySQL - How to Retrieve records from database

I am new to JTA and I need a method to retrieve some some elements from the database. I can do this through EntityManager but that works only for ResourceLocal.
I want to know how can I do this:
Query q = em.createNamedQuery("AnyQuery");
q.getResultList();
without the use of EntityManager.
Any ideas?
The question itself shows that you don't understand any of the technologies you try to work with. You probably need to study some more general stuff before you do any actual development.
you are probably confusing JTA and JPA,
your statement about RESOURCE_LOCAL is not true (and irrelevant) - there are JTA and RESOURCE_LOCAL transactions and in Java EE you usually use the former,
your thought of using Named JPA queries without EntityManager is plain absurd and probably stems from misunderstanding of some kind (what would be the point of using named queries without an entity manager?),
saying "some elements from database" shows that you can't really tell the difference between records and mapped objects, in which case you probably should not use JPA at all.
I am not really expecting that you accept this answer. That's just my frustration taking over.
EDIT
OK, now that you mentioned JSF I understand more of your problem.
I assume you want to use JPA. In such case you have a choice of:
creating your own EntityManager (in such case you cannot have it injected; instead you have yo use an EntityManagerFactory and build your own). This is an "application managed EntityManager". You don't really want to do this.
using an injected EntityManaged ("conatiner managed EntityManager"). This is the standard choice.
Now you need a transaction. Since you should be using a JTA EntityManager, you will need a transaction object that is responsible for coordinating the whole thing. Again, you have two choices:
in a JSF bean, inject a UserTransaction (using #Resource annotation). This is messy, error-prone and takes a lot of boilerplate, but you will find all the necessary methods. You can create your own (application managed) EntityManager, call its joinTransaction method and then call begin-commit on UserTransaction. This is would be an "application managed transaction"
move your EntityManager code to EJB. It only takes a couple of lines of code and a single annotation (#Statless). All the code inside an EJB is - magically - wrapped inside a transaction that the container manages for you. This is the "container managed transaction" - the default and common choice.
Each of the things above could (and should) be expanded with some additional information. But the short path for you is:
create an EJB (a simple class with #Stateless annotation),
move the method that uses EntityManager to the EJB,
inject the EJB into your managed bean (using #EJB annotation) and call the relevant method.
The JTA transaction will happen around each call to any EJB method. This should get you started :-)

Should JPA Entity Manager be closed?

I have the method below.
public Profile readUser(String email){
EntityManager em = EMF.get().createEntityManager();
return em.find(Profile.class, email);
}
Is the above usage of entity manager okay? Or It is necessary to close em?Any suggestions please.
I suppose the answer is: it depends.
Your entity manager is the key to gain access to the context where entities reside. If your application is a JSE application, you have to consider what is the life expectancy of your context.
Let's consider that you will create an entity manager per user's request. So, while you are attending a given request, you will keep your entity manager open, and when you finish with it, you close it.
In a JSE application, you may have considered that you would like to keep your entity manager open the entire life of the application (supposing you're not dealing with big amounts of data) then you close it when your application shuts down.
Bottom line, when you open it and when you close depends entirely on your strategy and your design. You close it when you no longer need the entities in its context.
In your example, that is not evident, but since you're creating the EM in the method, you should close it before returning, otherwise, you will no longer have access to it again (unless you're keeping it in some registry, which is not evident in the code).
If you don't close it your entities will be kept as attached, even after you're done using them. Your context will be kept alive even when you can no longer access your EM.
The JPA Specification contains more details. In section 7.7 Application-managed Persistence Contexts it says:
When an application-managed entity manager is used, the application
interacts directly with the persistence provider's entity manager
factory to manage the entity manager lifecycle and to obtain and
destroy persistence contexts.
All such application-managed persistence contexts are extended in
scope, and can span multiple transactions.
The EntityManagerFactory.createEntityManager method and the
EntityManager close and isOpen methods are used to manage the
lifecycle of an application-managed entity manager and its associated
persistence context.
The extended persistence context exists from the point at which the
entity manager has been created using
EntityManagerFactory.createEntityManager until the entity manager is
closed by means of EntityManager.close.
An extended persistence context obtained from the application-managed
entity manager is a stand-alone persistence context it is not
propagated with the transaction.
[...] The EntityManager.close method closes an entity manager to
release its persistence context and other resources. After calling
close, the application must not invoke any further methods on the
EntityManager instance except for getTransaction and isOpen, or
the IllegalStateException will be thrown. If the close method is
invoked when a transaction is active, the persistence context remains
managed until the transaction completes.
The EntityManager.isOpen method indicates whether the entity manager
is open. The isOpen method returns true until the entity manager has
been closed.
To actually understand how this works it is vital to understand the relationship between the entity manager and the context.
So, as you can see the entity manager is the public interface through which you access your entities, however, your entities reside in a context, attached to your entity manager. Understanding the life cycle of the different types of contexts will answer your question.
Persistence contexts can be of different types. In Java EE applications, you can either have a transaction-scoped persistence context or a extended-persistence context. In the JSE application, the nature of the context is controlled by the developer.
When you ask for an entity to your entity manager, it looks for the entity in its attached context, if it finds the entity there, then it returns it, otherwise, it retrieves the entity from the database. Subsequent calls for this entity in context will return the same entity.
Transaction-scoped
In a Java EE application using the transaction-scoped persistence context, when you first access your entity manager, it checks if the current JTA transaction has a context attached if no context is yet present, a new context is created and the entity manager is linked to this context. Then the entity is read from the database (o from the cache if present) and it is placed into the context. When your transaction ends (commit or rollback), the context becomes invalid and whatever entities in it become detached. This is the classical scenario for stateless sessions beans.
#PersistenceContext(unitName="EmplService")
EntityManager em;
This also means that depending on how you design your transactions, you may end up with more than one context.
Extended-Persistence Context
In a Java EE application with stateful session beans you might like the context to survive multiple bean invocations, since you don't like to commit until the bean has been marked for removal, right? In those cases, you need to use an extended persistence context. In this case, the persistence context is created when it is first needed, but it won't become invalid until your mark the stateful bean for removal.
#PersistenceContext(unitName="EmplService", type=PersistenceContextType.EXTENDED)
This means that, regardless of the instance of the entity manager that gets injected into this bean in subsequent calls of the stateful session beans methods, you can be sure you will always access the same context, and therefore, even subsequent calls will return the same instance, because it is the same context.
Also, your changes will not be flushed until the bean is marked for removal or you manually flush them.
Application-Managed
You can always instantiate manually your entity manager factory and your entity manager. This is what you would typically do in a JSE application, is that right?
For this kind of applications you typically do not have a container to deal with the JTA transactions, right? So you use resource-local transactions and you are responsible for manually committing or rolling back changes.
For this kind of application, when you instantiate your entity manager, a context is automatically attached to it.
Depending on your application, you can decide to create a global entity manager whose life cycle is attached to the life of the application itself. That is a single entity manager for the entire life of the application. In this cases, your context will be created and destroyed with your entity manager.
Or, you could create an entity manager per conversation (i.e. transaction) with your application user. The scope, in this case, is determined by you, but still, your context will be created and destroyed with your entity manager.

Simple but good pattern for EJB

What would you suggest as a good and practical but simple pattern for a solution with:
HTML + JSP (as a view/presentation)
Servlets (controller, request, session-handling)
EJB (persistence, businesslogic)
MySQL DB
And is it necessary to use an own layer of DAO for persistence? I use JPA to persist objects to my DB.
Should I withdraw business logic from my EJB? All online sources tell me different things and confuses me...
I would definitely put the business logic in Stateless Session Beans. Stateless session beans are nice as they nicely capture the transaction boundaries. And it decouples the View layer from the persistence layer.
Take care that the methods of the SSB correspond to small business goals the user wants to achieve.
Another point is that you must be sure that the data you return has all data in the object tree and that you do not rely on lazy loading to get the rest, because this causes all kind of problems.
Stay as far away as possible from Stateful Session Beans : they are bad news and are a broken concept in the context of a web application.
For long running things, consider using Message Driven Beans which you trigger by sending a JMS message. These are a nice way to do background processing which frees the business logic faster, keeps transactions shorter and returns control to the end user faster.
What would you suggest as a good and practical but simple pattern for a solution with JSP/Servlets + EJB + MySQL
Use the MVC framework of your choice, Stateless Session Beans for the business logic and transaction management (prefer local interfaces if you don't need remoting), Entities for persistence.
Inject your EJBs wherever possible (if you are using Java EE 6, this means anywhere and you can also skip the interface).
And is it necessary to use an own layer of DAO for persistence? I use JPA to persist objects to my DB.
Some might say yes, I say no in most cases. The EntityManager already implements the Domain Store pattern, there is no need to shield it behind a DAO for simple needs.
You might want to read the following resources for more opinions on this:
Has JPA Killed the DAO?,
JPA/EJB3 killed the DAO,
and the more recent DAOs Aren't Dead - But They Either Collapsed Or Disappeared
Should I withdraw business logic from my EJB?
I wouldn't. Put your business logic in your (Stateless) Session Beans. EJB3 are POJOs, they are easily testable, there is no need to delegate the business logic to another layer.
Anno 2012 I would not recommend going for Servlets and JSP as the presentation layer. This was all the rage in 2002, but that's a decade ago.
Today Java EE has an excellent MVC framework build in called JSF. You are much better off using this instead. You most likely want to fetch some Widgets from the component library PrimeFaces, as all the standard ones are a bit basic. A utility library like OmniFaces is a great addition as well.
Regarding the DAOs; don't go as far as directly using the entity manager in (JSF) backing beans, but if you are already using Service classes (transactional boundaries) for your business logic , using a DAO as well might be overkill.
There are still some small advantages of a DAO, like a dao.findByName(...) looks a little clearer than loading a named query, setting a parameter, and getting a (single) result, but the cost is that you have to maintain a seperate DAO for each Entity, probably in addition to some Service.

EntityManager initialization best practices

When using EntityManager, is it better to get one instance with PersistenceContext and pass it around in my program, or should I use dependency injection more than once?
In my application each client will communicate with a stateful session bean, and each bean needs to use EntityManager at some point.
I guess that bean methods are invocated concurrently (but I'm not even sure).
How do I guarantee that I use EntityManager in a thread-safe manner? With transactions? With a separate instance in each bean?
Sorry if this is confusing, I'm new to EJB/JPA and I couldn't find any material which addresses my questions.
Yes, you should inject the EntityManager instances (which will be different for each thread/client request) into your stateful session beans (which are not invoked concurrently, at least not from different clients).
There is no point in creating DAO classes, though. JPA already is a high-level persistence API that gives you RDBMS independence and portability between different JPA implementations. So, DAOs would only add clutter to the codebase.
For transactions, you don't really need to do anything. Business methods in session beans have a "Required" transaction attribute by default, so they will always run inside a client-specific transaction.
Use #PersistenceContext to inject your EntityManager in your DAO class(es). These are the classes that will handle the database operations. Then in all other (service) classes inject your DAO class(es). Your DAO should be a stateless bean (no need of a remote interface, only local)

Categories