Am I using EJBs properly? - java

I am using a JEE6 stack including JPA 2.0, JSF 2.0, EJB 3.1 etc.
The way my architecture is setup is the following:
I have JPA annotated DAOs using hibernate as my JPA provider.
I have JSF Managed beans which correspond to my facelet/xhtml pages.
I have EJBs that handle all of my database requests.
My XHTML pages have JSF EL which make calls to my Managed beans. My managed beans contain references to my DAO entities which are managed by EJBs. For example, I have a user entity which is mapped to a db table. I have a user EJB which handles all CRUD operations that return Users. I have a page that edits a user. The highlevel workflow would be: navigate to user edit page -> EL calls a method located in the managed bean that loads a user. The method calls userEJB.loadUser(user) from the EJB to get the user from the database. The user is edited and submit -> a function is called in the managed bean which calls a function in the EJB to save the user. etc.
I am running into issues accessing my data within my JSF pages using EJBs.
I am having a lot of problems with lazy initialization errors, which I believe is due to how I have set things up.
For example, I have a Client entity that has a List of users which are lazily loaded. In order to get
a client I call a method in my EJB which goes to the database, finds a client and returns it. Later on
i wish to access this clients list of users, in order to do so i have to go back to the EJB by calling some sort of method in order to load those users (since they are lazily loaded). This means that I have to create a method such as
public List<User> getUserListByClient(Client c)
{
c = em.merge(c); return c.getUserList();
}
The only purpose of this method is to load the users (and I'm not even positive this approach is good or works).
If i was doing session management myself, I would like just leave the session open for the entire request and access the property directly, this would be fine as the session would be open anyway, there seems to be this one extra layer of indirection in EJBs which is making things difficult for me.
I do like EJBs as I like the fact that they are controlled by the container, pooled, offer transaction management for free etc. However, I get the feeling that I am using them incorrectly, or I have set up my JSF app incorrectly.
Any feedback would be greatly appreciated.
thanks,

If i was doing session management
myself, I would like just leave the
session open for the entire request
and access the property directly, this
would be fine as the session would be
open anyway
Indeed, that's the open session in view pattern (also called open EntityManager in view). It can be used with EJB as well. Ideally, the transactions should be managed in the business layer/EJB so this can be seen a slight deviation from the pure layer architecture. But it solves the problem of lazy loading in the view and is easy.
Otherwise, you must make sure to eagerly load the information that will be used after the transaction is over. Or you may rely on DTO, but then it starts to be cumbersome.
Here are two more links that cover the topic and discuss pros/cons and alternatives:
SO question: Open Session In View Pattern
Xebia blog: JPA implementation patterns and especially this one

Your usage seems good. Just remember that em.merge(c) may save the changes made to Client c into the database. If you just want to get the UserList of Client c without saving the changes made to the Client c, then you can do this:
public List<User> getUserListByClient(Client c)
{
Client client = em.find(Client.class, c.clientId);
return client.getUserList();
}
Or better ,just send the Client Id to the getUserListByClient instead of passing a full Client object , just to save a tinsy winsy bit of memory :)

Related

How to design layer architecture for web application?

I have design issue when implement 1 simple web application.
I use struts2 web controller, spring’s IOC and Hibernate as persist layer.
Because this web application is very simple at begging. So I only have 2 layers:
1 DAO layer which used to access database. Almost every table have related DAO.
2 Action layer. User struts2.
I am satisfy with this architecture because can quickly implement my web application.
As project become bigger, I found the action layer become big and complex, and very hard to re-use.
I try to create service layer, to solve complex business logic is good, but my application still have a lot of simply logic. E.g: Load 1 object, save 1 object, and get collection by some condition and display it to webpage. If give each simple DB access method have corresponding service method. Still cost a lot of effort. How can solve this issue?
And I think, if service layer existing, direct call DAO layer still not good design for my application.
Is any good solution for this kind of small web application?
When planing the different layers in a web application it is good practice to explicitly protect attributes and associations in your model from being manipulated without providing an identity context.
This is something that should neither be done in the DAO layer nor in the Controller. You should wrap your DAO layer in a service layer and have the controller only talk to the services not the DAO directly.
Protecting your model against unwanted manipulation means that you for instance adapt the amount of information passed in a data structure between Controller and Service to the actual operation that you want to perform.
For instance: adding or removing an element from a collection is an explicit operation in the service, it does not happen implicitly by manipulating a collection as a member of a DAO object and passing that DAO back into the service.
Instead your service may look like this:
+ getAllCompanies(): CompanyType[*]
+ getAllEmployeesOfCompany(c: CompanyType) : EmployeeType[*]
+ addEmployeeToCompany(e: EmployeeType, c: CompanyType)
+ removeEmployeeFromCompany(e: EmployeeType, c: CompanyType)
The additional benefit of such an architecture is that the service layer serves as boundary for your transactions. Using the methods of your controller as boundary for your transactions is in fact a very bad habbit. You could even call it an anti-pattern. Why? Because for instance it would mean that when your client hangs up it would roll back your transaction. That is clearly unwanted in 99% of the cases.
As #mwhs commented, Apache Isis provides plenty of guidance on layering your app. To figure out whether it fits your requirements, you could run through this tutorial I presented at a recent conference.

JSP beans - Read the DB each time I load the page?

I have no code done yet but I'm thinking on how I'm supposed to do this in JSP/JSF.
So, I have some classes I was thinking I could load from a DB whenever the session starts. My first idea is that I just load them once with the necessary data from the DB, do all the operations, and then destroy the bean when the session is done. The problem is, what if another user changes information during the session? So I thought I could use a page scope, however I don't want to overload the server.
What's the best practice on this?
Firstly, each visitor to your app gets their own session-scoped bean, so you've only got to worry about persisting each user's changes to the data on the bean.
Secondly, you are worrying about matters which are taken into consideration by ORM offerings. Using the API provided by something like Spring JPA or Hibernate will present you with controls for persisting data changes back to the DB via a local handle on a Bean.
I decided to use an application scoped bean instead of a singleton class. That will do.

.java terms and random words clarification

Im really new to java, jsf, jsp, and I need to learn how it works quickly. So the website Im using to practise has some terms etc that I dont know what they mean and Im hoping somebody can explain what they mean and how/what they are used for:)
Requestscoped
Applicationscoped
Sessionscoped
EntityManager
and could someone walk me through what these lines do?
#RequestScoped
public class Dao {
#DataRepository
#Inject
private EntityManager entityManager;
First of all, in Java (5 and higher), "things" starting with a # (e.g. #Deprecated) are called annotations.
Annotations provide data about a
program that is not part of the
program itself. They have no direct
effect on the operation of the code
they annotate.
Your JavaBeans needs to be configured to a scope if you want to use it in JSF (Definitions can be found here).
#RequestScoped: Objects with this scope are visible from the start of the request until the end
of the request. Request scope starts at the beginning of a request and ends when the
response has been sent to the client. If the request is forwarded, the objects are visible
in the forwarded page, because that page is still part of the same request/response
cycle. Objects with request scope can use other objects with none, request, session,
or application scope. If you have to think it in terms of servlet, the managed bean is stored in the HttpServletRequest until the end of the request (when the response is sent to the client). After that, the bean no longer exists in the request.
#SessionScoped: An object with session scope is visible for any request/response cycle that
belongs to a session. Objects with this scope have their state persisted between
requests and last until the object or the session is invalidated. Objects with session
scope can use other objects with none, session, or application scope. Basically, these objects are stored in a HttpSession (refer to Servlets again). Each session has a session ID (known as JSESSIONID) that the bean is associated with.
ApplicationScoped: An object with application scope is visible in all request/response cycles
for all clients using the application, for as long as the application is active. In terms of Servlet, this could be, managed bean stored in a ServletConfig.
#NoneScoped: Objects with this scope are not visible in any JSF page. When used in the configuration file, they indicate managed beans that are used by other managed beans in the application. Objects with none scope can use other objects with none scope.
For EntityManager, this is associated with persistence context. It is used to create and remove persistent entity instances, to find entities by their primary key identity, and to query over all entities. For more, refer to the JPA (Java Persistence API) Specification, or Hibernate.
#Inject, means that the instance is injectable. They follow the infamous crase word of Depency Injection or Inversion of Control (IOC). What this basically mean, is that when the resource (in your case EntityManager entityManager is needed, the JEE container instantiates the resource for you (without you needed to instantiate it directly through e.g. a constructor, etc.).
I have no clue what #DataRepository means. Never seen it before.
I hope this helps you.
These terms are usually associated with a dependency injection framework like guice and not with java in particular.
http://code.google.com/p/google-guice/wiki/Scopes describes the various scopes that are built into guice.
By default, Guice returns a new instance each time it supplies a value. This behaviour is configurable via scopes. Scopes allow you to reuse instances: for the lifetime of an application (#Singleton), a session (#SessionScoped), or a request (#RequestScoped). Guice includes a servlet extension that defines scopes for web apps. Custom scopes can be written for other types of applications.

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.

A typical lifecycle of a Hibernate object in a web app -?

Describe please a typical lifecycle of a Hibernate object (that maps to a db table) in a web app.
Suppose, you create a new instance of an object and persist in the db.
But during the app lifetime you'll be working on a detached object and finally
you need to update it in the database, for example on exit.
How does it look like with hibernate and spring?
p.s. Can transactions and sessions live between servlet transitions? So that we opened 1 session and use it in all servlets without a need to reopen it?
I'll try to give a descriptive example.
Suppose, when the app starts, the log record is created. this can be done at once,
Log log = new Log(...) and then something like save(log) -- log corresponds to a table LOG.
then, as the application processes user inputs and keeps going, new data is being accumulated.
and after the second step we could add something to a log object, a collection for example:
// now we have a tracking of what user chosen: Set thisUserChoice,
// so we can update the persistent object, we have new data now !
// log.userChoices = thisUserChoice.
Here occurs the nature of my question. How are we supposed to deal with it, if we want to
update the database whenever new data is gotten from a user?
In a relational model we can work with a row id, so we could get this record and update some other data of the row.
In Hibernate we are also able to load a object by its id.
But is IT THE WAY TO GO? IS ANYTHING BETTER?
You could do everything in a single session. But that's like doing everything in a single class. It could make sense from a beginner's point of view, but nobody does it like that in practice.
In a web app, you can normally expect to have several threads running at once, each dealing with a different user. Each thread would typically have a separate session, and the session would only have managed instances of the objects that were actually needed by that user. It's not that you can completely ignore concurrency in your own code, but it's useful to have hibernate's help. If you were to do everything with one session, you would have to do all the concurrency management yourself.
Hibernate can also manage the concurrency if you have multiple application servers talking to a single database. The separate JVMs can't possibly share the same session in this case...
The lifecycle is described in the hibernate documentation (which I'm sure you've seen).
Whenever a request comes from the web client to the server, the first thing you should do is load the relevant objects (see section 10.3) so that you have persistent, not detached entities to deal with. Then, you do whatever operations are required. When the session closes (ie. when the server returns the response to the client), it will write any updates to the database. Or, if your operation involves creating new entities, you'll have to create transient ones (with new) and then call persist() or save() (see section 10.2). That will result in a managed entity -- you can make more changes to it, and hibernate will record those changes when the session closes.
I try to avoid using detached objects. But if I have to (perhaps they're stored in the user's session), then whenever they might need to be saved to the database, you'll have to use update() (see section 10.6). This converts it into a managed object, and so the session will save any changes to the database when it's closed.
Spring makes it very easy to generate a new session for each request. You would normally tell Spring to create a sessionFactory, and then every request will be given its own session. Search for "spring hibernate tutorial" and you'll find several examples.
http://scbcd.blogspot.com/2007/01/hibernate-persistence-lifecycle.html This explains transient, persistent objects.
Also have a look at the Lifecycle interface to know what hibernate does (and it provides hooks at all stages for user to do something)

Categories