http://onjava.com/onjava/2001/10/02/ejb.html
Systems that have JSP/servlet front-ends should use HttpSession objects to store session-oriented state on behalf of a client. Applications that manage an HttpSession object and an SFSB for a single client wind up duplicating effort that does not need to be duplicated. There are two reasons to use an SFSB in conjunction with an HttpSession object:
Month: April 2013
Understanding Association, Aggregation, and Composition
source: http://www.codeproject.com/Articles/330447/Understanding-Association-Aggregation-and-Composit
|
Table of contents
- Introduction
- Extracting real world relationships from a requirement
- Requirement 1: The IS A relationship
- Requirement 2: The Using relationship: Association
- Requirement 3: The Using relationship with Parent: Aggregation
- Requirements 4 and 5: The Deathrelationship: Composition
- Putting things together
- The source code
- Summarizing
- Video on Association, Aggregation, and Composition
Introduction
In this article, we will try to understand three important concepts: association, aggregation, and composition.
We will also try to understand in what kind of scenarios we need them. These three concepts have really confused a lot of developers and in this article, my attempt would be to present the concepts in a simplified manner with some real world examples.
Extracting real world relationships from a requirement
The whole point of OOP is that your code replicates real world objects, thus making your code readable and maintainable. When we say real world, the real world has relationships. Let’s consider the simple requirement listed below:
- Manager is an employee of XYZ limited corporation.
- Manager uses a swipe card to enter XYZ premises.
- Manager has workers who work under him.
- Manager has the responsibility of ensuring that the project is successful.
- Manager’s salary will be judged based on project success.
If you flesh out the above five point requirement, we can easily visualize four relationships:-
- Inheritance
- Aggregation
- Association
- Composition
Let’s understand them one by one.
Requirement 1: The IS A relationship
If you look at the first requirement (Manager is an employee of XYZ limited corporation), it’s a parent child relationship or inheritance relationship. The sentence above specifies that Manager is a type of employee, in other words we will have two classes: parent class Employee
, and a child class Manager
which will inherit from theEmployee
class.
Note: The scope of this article is only limited to aggregation, association, and composition. We will not discuss inheritance in this article as it is pretty straightforward and I am sure you can get 1000s of articles on the net which will help you in understanding it.
Requirement 2: The Using relationship: Association
Requirement 2 is an interesting requirement (Manager uses a swipe card to enter XYZ premises). In this requirement, the manager object and the swipe card object use each other but they have their own object life time. In other words, they can exist without each other. The most important point in this relationship is that there is no single owner.
The above diagram shows how the SwipeCard
class uses the Manager
class and the Manager
class uses theSwipeCard
class. You can also see how we can create objects of the Manager
class and SwipeCard
class independently and they can have their own object life time.
This relationship is called the “Association” relationship.
Requirement 3: The Using relationship with Parent: Aggregation
The third requirement from our list (Manager has workers who work under him) denotes the same type of relationship like association but with a difference that one of them is an owner. So as per the requirement, theManager
object will own Worker
objects.
The child Worker
objects can not belong to any other object. For instance, a Worker
object cannot belong to aSwipeCard
object.
But… the Worker
object can have its own life time which is completely disconnected from the Manager
object. Looking from a different perspective, it means that if the Manager
object is deleted, the Worker
object does not die.
This relationship is termed as an “Aggregation” relationship.
Requirements 4 and 5: The Death relationship: Composition
The last two requirements are actually logically one. If you read closely, the requirements are as follows:
- Manager has the responsibility of ensuring that the project is successful.
- Manager’s salary will be judged based on project success.
Below is the conclusion from analyzing the above requirements:
- Manager and the project objects are dependent on each other.
- The lifetimes of both the objects are the same. In other words, the project will not be successful if the manager is not good, and the manager will not get good increments if the project has issues.
Below is how the class formation will look like. You can also see that when I go to create the project object, it needs the manager object.
This relationship is termed as the composition relationship. In this relationship, both objects are heavily dependent on each other. In other words, if one goes for garbage collection the other also has to be garbage collected, or putting from a different perspective, the lifetime of the objects are the same. That’s why I have put in the heading “Death” relationship.
Putting things together
Below is a visual representation of how the relationships have emerged from the requirements.
The source code
You can download the sample source code for this article.
Summarizing
To avoid confusion henceforth for these three terms, I have put forward a table below which will help us compare them from three angles: owner, lifetime, and child object.
Association | Aggregation | Composition | |
Owner | No owner | Single owner | Single owner |
Life time | Have their own lifetime | Have their own lifetime | Owner’s life time |
Child object | Child objects all are independent | Child objects belong to a single parent | Child objects belong to a single parent |
Video on Association, Aggregation, and Composition
I have also added a video in case you do not want to read this long article.
Just a note: I have recorded around 500 videos, do have a look at my videos on .NET, OOP, SQL Server, WCF, Silver light , LINQ , VSTS, SharePoint, Design Patterns, UML and a lot more.
Thanks for reading my article.
License
About the Author
Shivprasad koirala |
E-learning company in India. We are very much active in making training videos ,
writing books and corporate trainings. Do visit my site for
.NET, C# , design pattern , WCF , Silverlight
, LINQ , ASP.NET , ADO.NET , Sharepoint , UML , SQL Server training
and Interview questions and answers
Managing EntityManager without EJB / Dependence Injection
source http://javanotepad.blogspot.sg/2007/08/managing-jpa-entitymanager-lifecycle.html
In order to decide your best approach, you need to keep in mind that:
- An EntityManager is not a heavyload object.
- It’s not safe to traverse lazy-loaded relationships once the EntityManager is closed (This situation will change as ofJPA 2.0).
Because of the first issue, there is no need to use the same EntityManger longer than needed, so there is neither room for application scope nor session scope. In addition to the first issue, note that you can’t use an EntityManager instance for the whole application lifecycle (application scope) for the EntityManager is not Thread-safe.
Only two scopes are left:
- Method scope (i.e. instantiate/destroy one EntityManager in each business method).
- Request scope.
Using EntityManager with method scope
You create and destroy the EntityManager instance within a business method.
Be careful to ensure the EntityManger is always closed. When dealing with transactions it could be a little tricky as it was commented in this post.
Dealing with this scope is easy, here is a sample:
public void aBusinessMethod() {
EntityManagerFactory emf = ... ;
EntityManager em = emf.createEntityManager();
try {
...
} finally {
em.close();
}
}
However, this method scope is not enough for every situation. There could be some scenarios where you’ll need a wide scope, such as the following situations:
- When transactions spread multiple business methods.
- Need to traverse lazy-loaded relationships outside a method (e.g. in a JSF page).
In these scenarios you can choose to keep one EntityManager for the whole life of a HTTP request as we are about to describe.
Before stepping further into the request scope strategy, you can think of a little workaround in order to avoid using the latter (this workaround is not my favorite alternative). It is based on forcing eagerly the loading of relationships of entities and can be useful when you need to traverse them once the EntityManager has been closed. One of such a typical scenario is traversing a relationship from within a JSF page.
Loading eagerly relationships
As a reminder, the JPA relationships that by default are lazily loaded are: OneToMany and ManyToMany.
Loading eagerly these relationships can be done in two different ways:
- Changing the domain model
- Explicit loading of relationships
The first one is referring to explicitly use the parameter fetch of the JPA annotation @OneToMany or @ManyToMany as in the sample:
@OneToMany(fetch=FetchType.EAGER)
The problem with this solution is that you define a requirement in your domain model instead of solving the problem just when you really need it.
Loading explicitly relationships can be done at first sight by invoking the method on the entity that get access to the collection of entities, however this is not very reliable: for instance, when we traverse a OneToMany relationship with Hibernate EM as the JPA engine, the returned collection (proprietary implementation) has not loaded its entities at all. In spite of returning a collection, its elements are not loaded till you really access each one (or invoke the size() method of the collection to force this loading)!
Using EntityManager with request scope
This is a one EntityManager per HTTP request strategy with the following features:
- Creation on demand of the EntityManager.
- Lazy closing of the EntityManager.
We’ll provide an on-demand creation of the EntityManager instance to use within the request service. So if theEntityManager is not needed for a given request, it won’t be create at all!
The main benefit of this scope is derived from the delayed closing of the EntityManager (it will last as long as a HTTP request is in process). Every queried entity will be managed till the end of the request and therefore during the presentation phase (the render phase in JSF for instance). This allows you to traverse lazy loaded relationships in a transparent manner: you no longer have to force the loading of relationships as commented before (they will be loaded only if they are traversed: on demand).
Another benefit is the possibility to share the EntityManager instance among several business methods within a request (with no need to pass the EntityManager as parameter). This is not a limitation, in case you would need more than oneEntityManager instance you’ll be able to bypass this utility and create directly an EntityManager instance yourself.
Transparent Design for an EntityManager with a lazy closing behaviorAs a requirement, our approach will be transparent from a client perspective.That is, the client code should not change in order to provided this behavior (this way, you can easily adapt your web application). This is the typical client code using the EntityManager inside a method:
EntityManagerFactory emf = ...
EntityManager em = emf.createEntityManager();
try {
...
} finally {
em.close();
}
In order to provide this transparency, we’ll create proxies for the EntityManagerFactory and EntityManager classes. The following UML class diagram, based on the Proxy Pattern, shows abstract proxies and the concrete classes:
Instead of creating one class for every proxy we have chose to create an abstract proxy class to be used as a generic multi-purpose base class, and we have provided the actual proxy as a concrete class extended from the the abstract proxy.
You can take a look to the EntityManagerFactoryProxy class:
abstract class EntityManagerFactoryProxy implements EntityManagerFactory {
protected final EntityManagerFactory delegate;
protected EntityManagerFactoryProxy(EntityManagerFactory emf) {
this.delegate = emf;
}
public EntityManager createEntityManager() {
return delegate.createEntityManager();
}
public EntityManager createEntityManager(Map map) {
return delegate.createEntityManager(map);
}
public boolean isOpen() {
return delegate.isOpen();
}
public void close() {
delegate.close();
}
}
The EntityManagerProxy class (not shown here, see complete source from resources) is created likewise.
The ScopedEntityManagerFactory class is just a factory for LazyCloseEntityManager. And LazyCloseEntityManager class acts in behalf of the client to override the EntityManager.close() method in order to delay calling the close method of its delegate (actual EntityManager).
Binding Thread and EntityManagerOur design is based on a property all Application Servers must ensure: for a given request, the ServletRequestListener‘s methods and Serlvet‘s service method are executed in the same thread (regardless of the use of a thread pool to serve requests).
Taking advantage from this issue, we’re going to create a request listener whose responsibility is just to close the EntityManager bound to to the request thread (if it was created previously created).
Binding the EntityManager to the current thread can be done easily using a ThreadLocal object.
The class responsible for creating LazyCloseEntityManager is ScopedEntityManagerFactory and so the one who useThreadLocal. when a client asks for an EntityManager managed ScopedEntityManagerFactory will look up first in itsThreadLocal object. If the current thread asking for the EntityManager has already used it, No other EntityManger will be created, otherwise, ScopedEntityManagerFactory will create a new LazyCloseEntityManager and will bind it to the thread for future uses.
Somehow ScopedEntityManagerFactory should be notified when the HTTP request finishes for it must forget theLazyCloseEntityManager bound to its ThreadLocal object.
Finally the HTTP request listener is responsible for closing eventually the LazyCloseEntityManager and notifying of this event.
The following UML class diagram exposes these ideas:
As a facility, we’ll show some of the core classes that implements this design.
We’ll start with the factory of LazyCloseEntityManager instances, that is ScopedEntityManagerFactory. This is the only class using the ThreadLocal class. Note it is notified when each LazyCloseEntityManager instance is really closed.
public class ScopedEntityManagerFactory extends EntityManagerFactoryProxy
implements LazyCloseListener {
private final ThreadLocal<LazyCloseEntityManager> threadLocal;
protected ScopedEntityManagerFactory(EntityManagerFactory emf) {
super(emf);
this.threadLocal = new ThreadLocal<LazyCloseEntityManager>();
}
public EntityManager createEntityManager(Map map) {
LazyCloseEntityManager em = threadLocal.get();
if (em == null) {
em = new LazyCloseEntityManager(super.createEntityManager(map));
createEntityManager(em);
}
return em;
}
public EntityManager createEntityManager() {
LazyCloseEntityManager em = threadLocal.get();
if (em == null) {
em = new LazyCloseEntityManager(super.createEntityManager());
createEntityManager(em);
}
return em;
}
private void createEntityManager(LazyCloseEntityManager em) {
threadLocal.set(em);
em.setLazyCloseListener(this);
}
protected LazyCloseEntityManager getEntityManager() {
return threadLocal.get();
}
public void lazilyClosed() {
threadLocal.set(null);
}
}
Below you can see the LazyCloseEntityManager class. Note this class is a wrapper for the Actual EntityManager: It is created by ScopedEntityManagerFactory (through a ThreadLocal) and used by the HTTP request listenerPersistenceAppRequestListener:
public class LazyCloseEntityManager extends EntityManagerProxy {
private LazyCloseListener listener;
public LazyCloseEntityManager(EntityManager delegate) {
super(delegate);
}
public void setLazyCloseListener(LazyCloseListener listener) {
this.listener = listener;
}
public LazyCloseListener getLazyCloseListener() {
return listener;
}
@Override
public void close() {
}
protected void lazyClose() {
super.close();
if (listener != null) listener.lazilyClosed();
}
}
The important thing to highlight is that the real close() method has no effect: in case a client code invoke this method, it has nothing to do. lazyClose() method is the one who close the actual EntityManager and is invoked by the HTTP request listener as you can see next.
Here is the HTTP request listener. Note it only closes the LazyCloseEntityManager bound to the current thread.
public class PersistenceAppRequestListener implements ServletRequestListener {
public void requestInitialized(ServletRequestEvent evt) {
}
public void requestDestroyed(ServletRequestEvent evt) {
PersistenceManager pm = PersistenceManager.getInstance();
if (pm instanceof ScopedPersistenceManager) {
LazyCloseEntityManager em = ((ScopedEntityManagerFactory)pm
.getEntityManagerFactory()).getEntityManager();
if (em != null)
em.lazyClose();
}
}
}
Client code using the request scope EntityManager
The only requirement (in addition to include the library jar file) for a client web application to use the request scopeEntityManager is:
- Define a web listener.
- Determine the name of the Persistence Unit to use (optional).
Both modifications must be done in your web.xml deployment descriptor archive.
Configuring the web.xml archive
The name of the Persistence Unit that you want for this utility to use can be define as an init parameter in the deployment descriptor file web.xml:
<context-param>
<param-name>es.claro.persistence.PERSISTENCE_UNIT</param-name>
<param-value>MyPersistenceUnit</param-value>
</context-param>
Alternatively, you can define the name of the Persistence Unit programmatically by using this code:
PersistenceManager.setPersistenceUnit("MyPersistenceUnit");
If no Persistence Unit name is define neither within the web.xml archive nor using this code, an default name is assumed, that is “DefaultPU”.
You also need to explicitly define a HTTP listener in the deployment descriptor file web.xml as follows:
<listener>
<description>Listener for managing EntityManager with request scope</description>
<listener-class>es.claro.persistence.PersistenceAppRequestListener</listener-class>
</listener>
Actually, this listener acts as a request listener and as a servlet context listener.
From an user perspective, this is the listener which lazily close the EntityManager of the current HTTP request, so it would be fatal to forget to define this listener.
Sample code
The only class to know is PersistenceManager.
Through this singleton, you can create the EntityManagerFactory instance needed to begin to work with JPA (What you’ll obtain from PersistenceManager won’t be actually an EntityManagerFactory object but a proxy subclass of this class).
Below is a sample code using this approach:
EntityManagerFactory emf = PersistenceManager.getInstance().getEntityManagerFactory();
EntityManager em = emf.createEntityManager();
try {
EntityTransaction t = em.getTransaction();
try {
t.begin();
...
t.commit();
} finally {
if (t.isActive()) em.getTransaction().rollback();
}
} finally {
em.close();
}
Note that this client code is the same for method scope, so switching between a scoped and non-scoped EntityManager strategy is completely transparent to the client code!
Simplifying client code
An optional enhancement to this design can be done.
Just to add PersistentManager.getScopedEntityManager() as as shortcut method.
By using this method in client code, closing the EntityManager each time you use it can be avoid
EntityManager em = PersistenceManager.getInstance().getScopedEntityManager();
try {
em.getTransaction().begin();
...
em.getTransaction().commit();
} finally {
if (em.getTransaction().isActive()) em.getTransaction().rollback();
}
Note this code is just trivial if no transaction is involved.
A little drawback for coding this way is that you no longer can switch between scoped and non-scoped EntityManagerstrategy without changing the client code!
Resources
The whole source code of the request scope entity manager has been developed with Netbeans and hosted as a little open source project at Google Code, so you can access both the source code as well as a jar file with the library ready to use.
- Open Source Project.
- Library (jar file) ready to use (check the project main page for new releases).
According to TLD or attribute directive in tag file, attribute items does not accept any expressions
if you encountering error:
“According to TLD or attribute directive in tag file, attribute items does not accept any expressions”,
Please check your taglib on top of your JSP
Outdated:
<%@ taglib prefix=”c” uri=”http://java.sun.com/jstl/core” %>
<%@ taglib prefix=”c” uri=”http://java.sun.com/jsp/jstl/core” %>
Please change your taglib definition to the new one, it will save your time and rest your head.
Spring MVC bind exception in the form validation
A few minutes ago I found an intricate problem when using Spring MVC. Let’s jump directly to the code:
HomeWebController.java
….
@RequestMapping(method = RequestMethod.POST)
public String login( @Valid LoginRequest login, HttpServletRequest request,
HttpServletResponse response, BindingResult result
) {
request.setAttribute(“home”, login);
logger.info(“binding result=” + result);
if (result.hasErrors()) {
return “home”;
}…
return “feedbacklist”;}
….
home.jsp
….
<form:form commandName=”home” action=”home” class=”form” data-ajax=”false” method=”post”>
<form:errors path=”*” cssClass=”errorblock” element=”div” />
<form:input path=”username” placeholder=”Please enter your email” data-role=”none” class=”field topCurve” autocorrect=”off” autocapitalize=”off” type=”email” pattern=”[^ @]*@[^ @]*” />
<form:password path=”pwd” placeholder=”Please enter your password” data-role=”none” class=”field btnCurve” autocorrect=”off” autocapitalize=”off” />
<form:button class=”button rounded” id=”submithome” data-role=”none” type=”submit”>Submit</form:button>
</form:form>
After a few hours searching in the web, I found the answer.
There are 2 small thing are incorrect in the code above:
1. BindingResult parameter must be placed immediately after validated bean.
public String login( @Valid LoginRequest login, BindingResult result, HttpServletRequest request,
HttpServletResponse response
)
This is one of the Spring weakness. Spring is very rigid in the naming and parameter.
If we didn’t follow this, the following exception will occur:
org.springframework.validation.BindException: org.springframework.validation.BeanPropertyBindingResult: 1 errors
2. Naming in the jsp “<form:form commandName= …” and controller must according to the Bean Class.
Let say our java bean class is: “LoginRequest”, then we MUST name commandName attributes as “loginRequest”.
following is the correction:
home.jsp
<form:form commandName=”loginRequest” action=”home” class=”form” data-ajax=”false” method=”post”>
HomeWebController.java
@RequestMapping(method = RequestMethod.POST)
public String login( @Valid LoginRequest login, BindingResult result, HttpServletRequest request,
HttpServletResponse response) {
request.setAttribute(“loginRequest”, login);
logger.info(“binding result=” + result);
if (result.hasErrors()) {
return “home”;
}
…
return “/feedbacklist”;
}
Intricate huh?