Dear Wiki user,

You have subscribed to a wiki page or wiki category on "Tapestry Wiki" for 
change notification.

The following page has been changed by michaelcourcy:
http://wiki.apache.org/tapestry/Tapstry5First_project_with_Tapestry5,_Spring_and_Hibernate

------------------------------------------------------------------------------
  
  === Software architecture ===
  
- The main insterest of setting your software architecture this way is having a 
rigourous management of your ptoject, it garantees the maintainability, the 
evolutivity and the exploitation. The image below shows the architecture that 
we're going to set up in this tutorial. This type of architecture is widely 
regarded as efficient and could be applyed to any web project.
+ The main insterest of setting your software architecture this way is having a 
rigourous management of your project, it garantees the maintainability, the 
evolutivity and the exploitation of the application. The image below shows the 
architecture that we're going to set up in this tutorial. This type of 
architecture is widely regarded as efficient and could be applied to any web 
project.
  
  
[http://baptiste-meurant.developpez.com/tutoriaux/tapestry5-spring-hibernate/images/fig7.jpg]
  
  The main goal of this kind of architecture is to separate the concerns 
(buisness vs web) using a strict separation of layers. Indeed one can see on 
the previous image the 3 layers of this application :
  
   * DAO Layer : this layer manages the access to the database through the 
Hibernate framework.
-  * Service Layer : The layer represents all the buisness code, it organises 
the access to the DAO layer and manages all the transactionnal aspects. All of 
them are organized and manages by the Spring framework.
+  * Service Layer : The layer represents all the buisness code, it organises 
the access to the DAO layer and manages all the transactionnal aspects. All of 
them are organized and managed by the Spring framework.
-  * MVC Layer : This layer is the IHM, it's the client part of the 
application. It interacts with the Service layer depending of the client action 
and retreive the data to show them in a well formed way. This layer is 
undertaken by the Tapestry5 framework.
+  * MVC Layer : This layer is the IHM, it's the client part of the 
application. It interacts with the Service layer depending of the client action 
and retrieve the data to show them in a well formed way. This layer is 
undertaken by the Tapestry5 framework.
  
  Those layers must be decoupled, which means that there should be no 
dependencies between each other. Pratically this is possible by having each 
layer collborating to the other layer through interface. For instance the 
Service layer only know the interfaces of the DAO layer and the MVC layer only 
know the interfaces of the Service Layer. This way, each layer publish, through 
its interfaces, all the treatement that it can offer to the upper layer. And 
the link between the interface and the implementation, which introduces a 
technologic dependency (for instance the implementation of the DAO layer uses 
hibernate) is managed by Spring.
  
@@ -94, +94 @@

  
  Let's focus for a little while on the manipulation of the DB. The previous 
explainations show two aspects :
  
-  * The DAO layer publishstransactionnal contexte  its access methods to the 
DB, theses methods can search, create or delete records. Actually they can 
retreive objects from DB record, create new objects by creating new records in 
the DB, or delete object by deleting record in the DB.
+  * The DAO layer publishs its access methods to the DB, theses methods can 
search, create or delete records. Actually they can retreive objects from DB 
record, create new objects by creating new records in the DB, or delete object 
by deleting record in the DB.
   * The object relational mapping and the persistance of datas in a 
transactionnal context allow any change in the state of an object to be 
propagated in the DB through UPDATE actions.
  
  Thus the DAO layer won't features any methods to update the objects. Thoses 
aspects will be covered in greater details later on.
@@ -257, +257 @@

  
   * @Entity : declares to hibernate that this class is persistant.
   * @Table : to which table in the DB this entity must be mapped
-  * @Id : declare the property of the entity that is used as a primary key
+  * @Id : declares the property of the entity that is used as a primary key
   * @Column : map a a property in the entity to a column of the table. This 
annotation brings extra constraint informations like for instance non nullity 
or non mutabillity. These hints on the column let hibernate validate the 
constraints before acting in the DB.
  
  
@@ -293, +293 @@

  
  
[http://baptiste-meurant.developpez.com/tutoriaux/tapestry5-spring-hibernate/images/fig20.jpg]
  
- The Spring framework is on top of a invervion of control and injections 
dependencies engine. To have layers of the application properly decoupled, each 
class of a layer collabore with the interface of the other layer. Then the 
Spring framework inject at runtime the implementation code of the interface in 
the different classes. The developper make this possible by creating the 
getters and the setters of this interfaces, then Spring through xml 
configurations files use this setters to inject implementations of the 
interfaces.
+ The Spring framework is on top of an inversion of control and injections 
dependencies engine. To have layers of the application properly decoupled, each 
class of a layer collabore with the interface of the other layer. Then the 
Spring framework inject at runtime the implementation code of the interface in 
the different classes. The developper make this possible by creating the 
getters and the setters of this interfaces, then Spring through xml 
configurations files use this setters to inject implementations of the 
interfaces.
  
  Using this mechanism we're going to create two distincts layers: The DAO 
layer (Data Access Object) and the service layer (buisness layer), the two 
layers are going to collabore with each other through interfaces.
  
@@ -442, +442 @@

   * The use of the Hibernate Criteria API that let you make request based on 
Object. We could do the same thing with HQL but it's not as elegant as the 
Criteria API is.
   * The use of differents Spring interfaces for accessing the Hibernate (for 
instance getHibernateTemplate(), etc.).
  
- Create the xml file ApplicationContextDao.xml in WEB-INF and declare the 
couple interface/implementation using Spring's bean. By Default a Spring's bean 
is a singleton and thus are ThreadSafe. Thi means that this code could be 
concurently called by two different processes safly. This mechanism in 
internally managed by Spring.
+ Create the xml file ApplicationContextDao.xml in WEB-INF and declare the 
couple interface/implementation using Spring's bean. By Default a Spring's bean 
is a singleton and thus are ThreadSafe. This means that this code could be 
concurently called by two different processes safly. This mechanism in 
internally managed by Spring.
  
- This file define a bean userDao corresponding to the previous interface and 
we choose the implementation we want to use. This bean contains a property (in 
the JavaBeans sens) sessionFactory. The sessionFactory bean represents actually 
the Hibernate SessionFactory and has to be configured as well. The two mains 
configuration aspects of this beans is where to find the hibernate.cfg.xml and 
which strategy must be used for mapping entity to the DB tables, here it's the 
annotation strategy.
+ This file defines a bean userDao corresponding to the previous interface and 
we choose the implementation we want to use. This bean contains a property (in 
the JavaBeans sens) sessionFactory. The sessionFactory bean represents actually 
the Hibernate SessionFactory and has to be configured as well. The two mains 
configuration aspects of this beans is where to find the hibernate.cfg.xml and 
which strategy must be used for mapping entity to the DB tables, here it's the 
annotation strategy.
  
  {{{
  
@@ -581, +581 @@

  }}}
  
  
- The services layer need to collaborate with the dao layer. But following the 
principle of loose coupling, the service layer is going to collaborate with the 
interface of the dao not with its implementation. Spring has the duty to inject 
the implememtation in place of the interface at runtime. Two things need to be 
done to make this possible : provide in the service class a setter method for 
the dao and write the needed configuration in xml files.
+ The services layer need to collaborate with the dao layer. But following the 
principle of loose coupling, the service layer is going to collaborate with the 
interface of the dao not with its implementation. Spring has the duty to inject 
the implementation in place of the interface at runtime. Two things need to be 
done to make this possible : provide in the service class a setter method for 
the dao and write the needed configuration in xml files.
  
   * Edit UserManagerImpl to create the dao injector (actually its a setter). 
We also add two extras methods that we be needed for the next steps.
  
@@ -648, +648 @@

  }}}
  
  
- Notice that there's no reference to the implementation : only the interface 
is known and used via the locale variable userDao. At startup, Spring use the 
setter to inject the implementation you defined in ApplicationContextDao.xml. 
Thanks to the configuration of ApplicationContextDao.xml, all the method of 
UserDao become available (Caution : actually only the method defined in the 
interface are available, anyway trying to invoke a non interface method would 
end up in compilation error).
+ Notice that there's no reference to the implementation : only the interface 
is known and used via the locale variable userDao. At startup, Spring uses the 
setter to inject the implementation you defined in ApplicationContextDao.xml. 
Thanks to the configuration of ApplicationContextDao.xml, all the method of 
UserDao become available (Caution : actually only the method defined in the 
interface are available, anyway trying to invoke a non interface method would 
end up in compilation error).
  
  To make this injection effective, userManager need to be declared to Spring 
and must add the internal property userDao.
  
@@ -672, +672 @@

  
  }}}
  
- Once again we deal with the paradigm interface/implémentation with this time 
the use of injection through the definition of userDao which reference the bean 
defined before.  : the name of the bean must be exactly the name of the 
property defined in userManager. Spring will use camelise mechanism to invoke 
the setter : ie set + "U"serDao(userDAO);
+ Once again we deal with the paradigm interface/implementation with this time 
the use of injection through the definition of userDao which reference the bean 
defined before.  : the name of the bean must be exactly the name of the 
property defined in userManager. Spring will use camelise mechanism to invoke 
the setter : ie set + "U"serDao(userDAO);
  
  ==== Transaction management ====
  
- Beside inversion of control, dependencies injection and layering 
structuration of your code, Spring features powerful mechanism to manage the 
transactions. Transaction rely on proxy and PAO (Programmation Aspect 
Oriented), which is the core of the Spring Framework. You configure transaction 
in three steps :
+ Beside inversion of control, dependencies injection and layering 
structuration of your code, Spring features powerful mechanism to manage the 
transactions. Transaction rely on proxy and AOP (Aspect Oriented 
Programmation), which is the core of the Spring Framework. You configure 
transaction in three steps :
  
- First define a general abstract proxy that will be used by all the manager 
that need to be transactional : Add this code to applicationConextDao.xml
+ First define a general abstract proxy that will be used by all the manager 
that need to be transactional : Add this code to applicationContextDao.xml
  
  applicationContextDao.xml
  {{{
@@ -715, +715 @@

                        <ref bean="userDao" />
                </property>
        </bean>
-       <bean id="userManager" parent="transactionProxy">
+       <bean id="userManager" parent="transactionProxy">               
-               <property name="transactionManager">
-                       <ref bean="transactionManager"/>
-               </property>
                <property name="target">
                        <ref bean="userManagerTarget"/>
                </property>
@@ -731, +728 @@

  
  }}}
  
- Todo : check if the property transactionManager is not redundant.
  
  We put a transactionnal proxy in front of the buisness bean. The 
transactionManager is passed to the transactionnal proxy and we declare to 
Spring that the transaction configuration is done with annotation thanks to the 
property transactionAttributeSource.
  
@@ -897, +893 @@

  
  }}}
  
- Notice the attributes t:value that binds a the textefield value to a java 
variable. The atrribute for binds the html input to the label.
+ Notice the attributes t:value that binds the textefield value to a page 
property. The atrribute for binds the html input to the label.
  
  Create a package pages and a class Login.java which mirrors the html form :
  
@@ -968, +964 @@

  
  }}}
  
- ${login} uses the login variable in the session if defined. Tapestry can 
retreive this value if the context ApplicationState has been defined for both 
classes : Login.java and Home.java must bear the login property with the 
ApplicationState context.
+ ${login} uses the login variable in the session if defined. Tapestry can 
retrieve this value if the context ApplicationState has been defined for both 
classes : Login.java and Home.java must bear the login property with the 
ApplicationState context.
  
  The element t:actionLink define another link to a tapestry page. 
  
@@ -1018, +1014 @@

  
  }}}
  
-  * Once again, the annotation @ApplicationState will retreive the variable 
login from the session.
+  * Once again, the annotation @ApplicationState will retrieve the variable 
login from the session.
   * The annotation @Inject let tapestry inject dependencies from third parties 
source (here J2EE core).
-  * The method onLogout which thanks to the annotation 
@onEvent(component="logout") will be invoked every time the component bubble an 
event. Here, the component is a simple link, so every time one click on it the 
session is invalidated and the user comeback to the login page.
+  * The method onLogout which thanks to the annotation 
@onEvent(component="logout") will be invoked every time the component bubble an 
event. Here, the component is a simple link, so every time the link is clicked 
the session is invalidated and the user comebacks to the login page.
  
  Edit web.xml to configure the Tapestry filter and the base package from which 
tapestry knows where to find the pages package that contains page beans.
  {{{
@@ -1174, +1170 @@

  
  We notice :
  
-  * the annotations @Inject and @Service inject the bean (Manager) from Spring 
into Tapestry. We can now use all of the methods defined in the interface here 
we modify the methode onSucces, when the for is submitted the application 
called the Spring userManager service to execute the checkLogin method and 
check that login and password really exist in DB. If yes the user is redirected 
to the Home page. In the opposite, we initialise an error message variable to 
be diplayed to the user.
+  * the annotations @Inject and @Service inject the bean (Manager) from Spring 
into Tapestry. We can now use all of the methods defined in the interface here 
we modify the methode onSucces, when the form is submitted the application 
called the Spring userManager service to execute the checkLogin method and 
check that login and password really exist in DB. If yes the user is redirected 
to the Home page. In the opposite, we initialize an error message variable to 
be diplayed to the user.
   * The annotation @Persist on error persist the value of error only for this 
page : instead of the annotation @ApplicationState, @Persist define persistence 
only for the page not for the whole application.
   * The getErrorMessage make the property errorMessage available in the Login 
page. change Login.html :
  
@@ -1224, +1220 @@

  
  As we explained it at the beginning of this tutorial dealing with hibernate, 
every model object is related to a table in the DB. We therefore get a complete 
object graph : an entity having a 1,n relation with entity E2 in object realm 
is going to be object O1 of type T1 hold an object O2 of type collection of T2 
… And so on.
  
- We quickly realised that the object graph could be extremely heavy if all 
collections and children of children collections must be loaded. It's why by 
default, Hibernate uses "Lazy loading". Lazy loading means that when the object 
is loaded in memory, only the object is loaded not all its collections; 
collections will be loaded when they will first be used. The opposite of lazy 
loading is eager loading : when the object is loaded all the graph is loaded. 
You must explicitly annotate your classes to have eager loading (1,n ; n,1 ou 
n,n) : @OneToMany, @ManyToMany ou @ManyToOne(cascade = {}, fetch = 
FetchType.EAGER).
+ We quickly realized that the object graph could be extremely heavy if all 
collections and children of children collections must be loaded. It's why by 
default, Hibernate uses "Lazy loading". Lazy loading means that when the object 
is loaded in memory, only the object is loaded not all its collections; 
collections will be loaded when they will first be used. The opposite of lazy 
loading is eager loading : when the object is loaded all the graph is loaded. 
You must explicitly annotate your classes to have eager loading (1,n ; n,1 ou 
n,n) : @OneToMany, @ManyToMany ou @ManyToOne(cascade = {}, fetch = 
FetchType.EAGER).
  
  One very important thing to understand about lazy loading is that you can 
access to the lazy collections only if the transaction in wich you got this 
object is not commited yet. Indeed, the lazy loading is possible because the 
session Hibernate is still active and opened to be able to complete the graph 
from the DB when needed. And with the transaction manager we used in this 
tutorial, the session is closed at the end of the execution of the service 
method. Thus if we try to access a collection in the view we're going to have a 
LazyInitializationException.
  

---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to