I'm new in EJB & persistence at all, so excuse me please if I'll ask a stupid question.
I read a book about EJB and JPA, and faces phrase that I don't understand at all:
Intended to fully insulate developers from dealing directly with
persistence, it (EJB) introduced an interface-based approach, where
the concrete bean class was never directly used by client code.
Instead, a specialized bean compiler generated an implementation of
the bean interface to facilitate such things as persistence, security,
and transaction management, delegating the business logic to the
entity bean implementation.
and
The notion of container-managed entity beans was introduced, where
bean classes became abstract and the server was responsible for
generating a subclass to manage the persistent data.
What does it mean:
Specialized bean compiler generated an implementation of the bean interface
server was responsible for generating a subclass to manage the persistent data
Actually I can't grasp what mean generate implementation/subclass, does it mean in runtime?
Thank you in advance.
EDITED:
Finally, entity beans were modeled as remote objects that used RMI and
CORBA, introducing network overhead and restrictions that should never
have been added to a persistent object to begin with.
Does it also sink into nothingness?
1) Interfaces: To define a bean, you had to declare a Local interface and a Remote interface (if you were writting bean MyEJB, they had to be MyEJBLocal and MyEJBRemote; MyEJB would implement both). With that, the compiler generated some derived class implementing the methods, such methods would just connect to the EJB server to retrieve a bean and execute its methods.
I am not so sure about 2, since we had so many performance issues that we ended implementing JDBC logic in the Session beans (I know, I know)...
Specialized Bean: Since Java EE 5, EJB turn into annotation #EJB. All annotaion works like interface. This simple annotaion provide security, and transaction management, delegating the business logic at compile time.
JPA: No more entity bean remain since Java EE 5. Now if you put #Entity to on pojo than server will generate container-managed entity beans and communicate with database through persistance context.
Related
I read several articles informing that entity beans in a Java EE environment are considered as anemic (means only containing getters and setters without implementing behaviour).
What prevents me to put behaviour into entity beans ? So that session beans (stateless or stateful) could delegate all business logics to them (for logic making sense to be owned by entities).
I don't see why entity beans are necessarily anemic.
From a pure semantic perspective, you would expect an ENTITY bean to be a representation of an entity and its attributes. If you couple this with some logic, then you add additional responsibility to your entity class. And as we know from the Curly's law or the single responsibility principle, each class should do one thing and one thing only:
http://www.codinghorror.com/blog/2007/03/curlys-law-do-one-thing.html
http://en.wikipedia.org/wiki/Single_responsibility_principle
If you believe that you have a strong enough reason to violate this principle, you can, but as far in my experience, no reason was strong enough to violate standard software engineering practices, especially if you, like me, believe that the quality of software is best represented by the quality of its code.
There are no restrictions of implementing functionality on entity beans, but they're not meant to be used throughout your application so most of the time you'll add behaviors that modify entities on your Session Beans just because Session Beans are supposed to be accessed from the front end for example.
If we go deeper, session bean methods are usually decorated with transactional and security aspects while entity beans are not, so your application may not behave the expected way if you added code into entities.
The question basically sums it up.
Play framework has the JPABase class that JPA beans inherit from. This class has a method called em() which returns the bean's entityManager instance. Is there something equivalent to this in plain JPA?
AFAIK, no. And I would find it very questionable. JPA entities are supposed to be POJOs usable outside of the persistence layer, where the JPA classes are not even in the classpath. Exposing the EntityManager in those POJOs seems wrong to me.
It looks like the Play Framework implements the Active Record pattern allowing you to make persistence operations directly in the bean. This is perfectly acceptable and you can implement a similar solution.
However, once you choose this approach, you will not have the benefits of POJOs. For example, this solution may not be the best alternative if your application has n-tier architecture.
Anyway take a look at the source code, it's free!
https://github.com/playframework/play/blob/master/framework/src/play/db/jpa/JPABase.java
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.
Obviously using stateless EJB beans in an entity bean smells, but please consider a scenario as follows and tell me if you know of a better solution:
I have an InvoiceTemplate Entity Bean with field NextInvoiceDate
Generating NextInvoiceDate is a complex procedure and should be performed outside of the InvoiceTemplate class
NextInvoiceDate should be updated each time InvoiceTemplate is stored to the db
For now I have logic regarding the generation of NextInvoiceDate in #PrePersist #PreUpdate methon in InvoiceTemplate entity bean. The logic is getting more and more complicated and I want to move it outside of the InvoiceTemplate entity bean. It looks to me that there should be a service to calculate NextInvoiceDate. But then is it right to invoke this service from the inside of InvoiceTemplate?
It isn't such a smell - it is a lean towards domain-driven design.
I don't know of any way to do this automatically, but you can:
in the session beans where you handle your Invoicetemplate, inject the helper bean that has the logic to calculate the next date
create a private field with a setter on the entity, and before you start using it call entity.setNextDateHelper(..)
You can also check whether AspectJ doesn't offer some EJB options so that you can inject the EJB whenever an entity of a given type (InvoiceTemplate) is created. AspectJ works like that with spring beans, I don't know whether there are such options for EJB.
Do you need anything as complicated as a service or EJB? Can you just write a static method (possibly on a utility class) to hold the logic? Normally I'm pretty biased against this sort of thing, but if all you've got is some complex logic that doesn't require any DB interaction or a lot of object collaboration, it may be the cleanest approach.
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)