Im trying to get my head around CDI and EJB and the Entity Boundary Control (ECB) pattern. My understanding of the ECB pattern is that the Boundary is the start and end of the transaction boundary. Further to that, CDI doesn't provide transaction support like an EJB does.
So if I want to implement the ECB pattern successfully, then the following are true;
I can Implement the Boundary portion with EJB's (i.e. #stateless, #stateful, #singleton) and the Control layer with CDI or EJB's.
I can Implement the Boundary and Control portion with CDI but implement transaction support in the Boundary similar to (http://smokeandice.blogspot.com/2009/12/cdi-and-declarative-transactions.html)
I can not implement the Boundary with CDI and then start using EJB's in the Control layer.
Thanks
I sucessfully implement the ECB pattern in JavaEE 6 using EJB's solely for the Boundaries and CDI for the Controllers. A typical stack in my architecture uses
Stateless EJB's annotated with JAX-RS annotations to implement a REST service as Boundary
CDI managed beans for business logic in the #Dependent scope as Controller
CDI managed beans in the #Dependent scope for Data Access Objects which use JPA's EntityManager to interact with a database
JPA entity beans
The stateless EJB's which form the Boundary are always annotated with #TransactionAttribute(REQUIRED) which is the default. I do not use other transaction attributes. Doing so, you can ensure that every interaction with the Boundary takes place in exactly one transaction.
By using only the #Dependent scope for the CDI managed beans, you can ensure that every thread has its own instance of that beans. So you have never more than one thread accessing a CDI managed bean at the same time. Doing so prevents you from the typical concurrency issues.
Using a combination of more heavy weight, pooled EJB's for the Boundary and lightweight CDI managed beans for the rest of the application performs very well for me.
Related
My understanding is that
#Stateful
#ConversationScoped
is allowed, and is normal usage.
With the new JSF 2.2 ViewScoped (javax.faces.view.ViewScoped) annotation, which is documented to be fully compatible with CDI scope annotations, does this mean that:
#Stateful
#ViewScoped
Is a viable combination?
#Stateful is an EJB annotation, so technically your bean will be a stateful EJB bean, not a CDI bean. And it will only work in a full-blown application server.
In case of (only) JSF 2.2 + CDI use:
#javax.inject.Named // to expose a bean in the EL context
#javax.faces.view.ViewScoped // to make it view scoped
Also don't mix up the latter annotation with #javax.faces.bean.ViewScoped, it once took me a while to find the issue.
There's a nice example.
keep in mind that with #stateful, every time you inject it you will get a new concrete instance, because you're indicating storing state with that annotation. also the EJB layer concept of session is not the same as the JSF layer concept of session, and confusing the two can create all sorts of issues for you.
JSF session is tied to a specific client maintained by either a cookie or url-rewriting (container configuration).
EJB session is tied to a specific method execution (#Stateless) or a concrete instance (#Stateful).
unless you need to have durable serialization and state maintenance within the EJB, stateful is not going to give you want you want. you're best bet will be to separate the transactional aspects into a #Stateless and store your state in a #ViewScoped that gets passed into the #Stateless methods.
Usually I'm using #RequestScoped or #SessionScoped (from javax.enterprise.context) to inject objects (for instance in faces beans) using #Inject.
I am also using EJBs. As I understood, a set of stateless EJB copies (pool) is used to be injected to objects. The reason there are many copies is to ensure one instance of EJB isn't accessed concurrently. When speaking about stateful EJBs (again as I understood), one instance of such is bound to concrete injection point. And they are injected using #EJB (the stateless ones too).
Frequently I can see on the web examples of using #Stateless or #Stateful in conjunction with #Scoped. What is the meaning of them?
Edit: (trying to clarify as no one responded to this moment):
I'm especially interested whether such scoped annotations change anyhow (and if they - how) moment of creation of EJB's instance.
For my understanding: if I have, #EJB annotated field, object of proper class is injected there. If such EJB is stateless, container simply take free instance from the pool of pre-created instances. Pool can be resized if necessary. It is stateless, because object isn't guaranteed to be preserved across method calls of our class (i.e. class which has field containing reference to EJB).
We can also use stateful EJB and in that case one instance is preserved during method calls. As I think, it will be simply injected once per object creation. (There is also singleton EJB, which is shared between all objects).
I can't find the purpose of #Scoped annotations for EJB here.
Edit 2:
One can use such combination of annotations if class is to be injected via EJB and DI (by #Inject) mechanisms. This is rather, however, special case and not elegant. I am asking if you know any other reasons.
Edit 3:
Please see my comment under arjan's answer.
A #Stateless or #Singleton bean may be explicitly scoped to prevent its scope being automatically modified to a scope that may be illegal. E.g. both these bean types are not allowed to be #RequestScoped. See this link for some more info: http://docs.jboss.org/resteasy/docs/2.0.0.GA/userguide/html/CDI.html
#Stateful makes a lot of sense to be (explicitly) scoped. Namely, without a scope you as a programmer have to take care to call the #Remove annotated method. This can be troublesome to guarantee, since such a bean is typically not used in a single method where you can call the #Remove method in a finally block. With a scope, the bean is exactly removed when the scope ends.
Furthermore, without a scope you can't always use injection to obtain a reference to a stateful bean's stub. Namely, every time the injection happens, you'll get a new instance. This is particularly troublesome when injecting a stateful bean in a request scoped (JSF) backing bean, where you have the intent to preserve the stateful bean across a couple of requests.
Then, in combination with #Named, you can also use a session bean directly as a backing bean to flatten your application layers (see e.g. http://jaxenter.com/java-ee-6-overview-35987-2.html). Obviously you want an explicit scope in that case. Now flattening your layers may not be a best practice in larger applications, but for smaller applications and/or people just beginning with Java EE there is definitely a wish to put business logic directly into the backing bean. It's then required that backing beans have access to the same kind of services (mainly transactions) that 'business beans' normally have.
Finally, Gavin King (CDI spec lead) has suggested to always use #Inject instead of #EJB. The only exception concerns remote EJBs, where #EJB is still used.
Part of the confusion around EJB and CDI is that CDI is a new component model in Java EE and still relatively new. Although they integrate fairly well with each other, they are still two different component models and not all best practices have been thought out yet. Reza Rahman (EG member, EJB book writer, and author of CDI implementation CanDI) has suggested that the EJB model could possibly be retrofitted in the future as a set of CDI services. Indeed, in Java EE 7 a step is being made by separating the transactional services from EJB and making them available via (CDI) annotations.
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.
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.
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)