G53ELC
Using Spring and Hibernate
Dave Elliman
05/05/12
G53ELC
The overall architecture
G53ELC
05/05/12
G53ELC
The enterprise view (Java)
G53ELC
05/05/12
G53ELC
Revision - What is Dependency Injection?
G53ELC
DI is all about wiring up objects or plumbing if you prefer It is about ensuring loose coupling and fits well with design patterns Design to an interface and then inject the actual class at run time This is what inheritence is really for
05/05/12
G53ELC
A Real World Example?
G53ELC
Web App
Stock Quotes
Authenticator
Error Handler
Logger
Database
This example was originally created by Jim Weirich in Ruby on his blog.
05/05/12 G53ELC 5
Remember the old way
public class WebApp { public WebApp() { quotes = new StockQuotes(); authenticator = new Authenticator(); database = new Database(); logger = new Logger(); errorHandler = new ErrorHandler(); }
// More code here...
G53ELC
}
05/05/12 G53ELC 6
What about the child objects?
G53ELC How does the StockQuotes find the Logger? How does the Authenticator find the database? Suppose you want to use a TestingLogger instead? Or a MockDatabase?
05/05/12
G53ELC
Service Locator Interface
G53ELC public interface ILocator { TObject Get<TObject>(); }
05/05/12
G53ELC
Service Locator Example
public class MyLocator : ILocator { protected Dictionary<Type, object> dict = new Dictionary<Type,object>();
G53ELC
public MyLocator() { dict.Add(typeof(ILogger), new Logger()); dict.Add(typeof(IErrorHandler), new ErrorHandler(this)); dict.Add(typeof(IQuotes), new StockQuotes(this)); dict.Add(typeof(IDatabase), new Database(this)); dict.Add(typeof(IAuthenticator), new Authenticator(this)); dict.Add(typeof(WebApp), new WebApp(this)); } }
05/05/12 G53ELC 9
StockQuotes with Locator
G53ELC public class StockQuotes { public StockQuotes(ILocator locator) { errorHandler = locator.Get<IErrorHandler>(); logger = locator.Get<ILogger>(); } // More code here... }
05/05/12 G53ELC 10
Good things
G53ELC
Classes are decoupled from explicit imlementation types Easy to externalise the configuration
05/05/12
G53ELC
11
Dependency Injection Containers
G53ELC
Gets rid of the dependency on the ILocator Object is no longer responsible for finding its dependencies The container does it for you
05/05/12
G53ELC
12
Then what?
Write your objects the way you want G53ELC Setup the container Ask the container for objects The container creates objects for you and fulfills dependencies
05/05/12
G53ELC
13
Setting Up the Container (XML)
G53ELC <DIContainer> <TypeMap from=ILogger to=Logger /> <TypeMap from=IDatabase to=Database /> <TypeMap from=IErrorHandler to=ErrorHandler /> <TypeMap from=IQuotes to=StockQuotes /> <TypeMap from=IAuthenticator to=Authenticator /> </DIContainer>
05/05/12
G53ELC
14
Creating Objects
G53ELC [Test] public void WebAppTest() { DIContainer container = GetContainer(); IStockQuotes quotes = container.Get<IStockQuotes>(); IAuthenticator auth = container.Get<IAuthenticator>(); Assert.IsNotNull( quotes.Logger ); Assert.IsNotNull( auth.Logger ); Assert.AreSame( quotes.Logger, auth.Logger ); }
05/05/12 G53ELC 15
Existing Frameworks
G53ELC
Java
Pico Container Spring Framework HiveMind
Python
PyContainer
.NET Ruby
Rico Copland
Pico.NET Spring.NET p&p Object Builder
05/05/12
G53ELC
16
Spring with Persistence Layers
G53ELC
05/05/12
G53ELC
17
Spring can act as the Application
G53ELC
05/05/12
G53ELC
18
A persistent POJO for Hibernate
package elc; public class Tutor { private String id; /// unique identifier private String surname; private String firstname; private Tutor(); /// default constructor public Tutor(String id, String surname, String firstname) { this.id = id; this.surname = surname; this.firstname = firstname); } public String getId() {return id; } public String getSurname() {return surname; } public String getFirstname() {return firstname; } public void setId(String id) { this.id = id; } public void setSurname(String surname) { this.surname = surname; } public void setLogin(String firstname) { this.firstname = firstname; } }
G53ELC
05/05/12
G53ELC
19
The Hibernate Session
import org.hibernate.Session; import org.hibernate.SessionFactory; import org.hibernate.cfg.Configuration; ... some code Session = getSessionFactory().openSession(); Transaction tx = session.beginTransaction(); Tutor dave=new Tutor("dge","Elliman","Dave"); session.save(dave); tx.commit(); session.close(); ... more code
G53ELC 20
G53ELC
05/05/12
Tutor.hbm.xml
<?xml version='1.0' encoding='utf-8'?> <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"> <hibernate-mapping> <class name="elc.Tutor" table="tutor"> <id name="id" type="String" column="ID" > <generator class="assigned"/> </id> <property name="firstName"> <column name="FIRSTNAME" /> </property> <property name="surname"> <column name="SURNAME"/> </property> </class> </hibernate-mapping>
05/05/12 G53ELC
G53ELC
21
hibernate.cfg.xml
G53ELC
<?xml version='1.0' encoding='utf-8'?> <!DOCTYPE hibernate-configuration PUBLIC "-//Hibernate/Hibernate Configuration DTD//EN" "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd"> <hibernate-configuration> <session-factory> <property name="hibernate.connection.driver_class"> com.mysql.jdbc.Driver</property> <property name="hibernate.connection.url"> jdbc:mysql://localhost/hibernatetutorial</property> <property name="hibernate.connection.username">root</property> <property name="hibernate.connection.password"></property> <property name="hibernate.connection.pool_size">10</property> <property name="show_sql">true</property> <property name="dialect">org.hibernate.dialect.MySQLDialect</property> <property name="hibernate.hbm2ddl.auto">update</property> <!-- Mapping files --> <mapping resource="tutor.hbm.xml"/> </session-factory> </hibernate-configuration>
05/05/12
G53ELC
22
Using Hibernate with Spring
One simply creates a Hibernate Session Factory bean in G53ELC Spring: <bean id=sessionFactory class=org.springframework.orm.hibernate3.LocalSessio nFactoryBean> <property name=configurationClass value= org.bibernate.cfg.Annotation.Configuration /> <property name=configLocation value=classpath:hibernate.cfg.xml /> </bean>
05/05/12
G53ELC
23
An Intereface and a class to define
G53ELC public interface TutorDao { public void createTutor(final Tutor tutor); public Tutor getTutor(final String id); }
Also saveTutor(); deleteTutor() etc. CRUD is now done with single lines of code. No SQL needed
05/05/12 G53ELC 24
Do you get the CONCEPTS?
G53ELC You can look up the detail when you need it ELC exam will test the concepts and not the detail of xml configuration files of Java code You need to know that a configuration file is needed and what it does, not the fine detail of its formatting
05/05/12
G53ELC
25
Any Questions?
G53ELC Im confused
05/05/12
G53ELC
26
G53ELC
JEE and EJBs
Dave Elliman
05/05/12
G53ELC
27
POJOs and POJIs
Plain Old Java Objects and Interfaces G53ELC In the past EJBs were all rather different and special and you could not test them outside a container Now they are POJ you can
05/05/12
G53ELC
28
Annotations
G53ELC There has been a revolution in Server-side Java and Tiger Jane 1.5: EJB
annotations These are processed by a new tool called apt
You can write your own if you like
05/05/12
G53ELC
29
Writing EJBs was rather stereotyped
G53ELC An ideal situation for annotations. No longer need to write a Home interface No longer need an XML deployment descriptor (deploytool)
05/05/12
G53ELC
30
The Concept
G53ELC
Entity bean
corresponds to a set of records in a database
Session bean
handles business flow (one per client unless stateless, when may be shared)
05/05/12
G53ELC
31
Enterprise JavaBeans
Definition from OReillys Enterprise JavaBeans book
G53ELC
An Enterprise Java Bean is a standard serverside component model
Aha! Its a standard for building MIDDLEWARE In multi-tiered solutions
05/05/12
G53ELC
32
The Context in Which EJBs Are Used
G53ELC
EJB server EJB Home EJB Object EJB container EJBean
client
security
JNDI
JTS
..
33
05/05/12
G53ELC
It All Works by RMI
G53ELC Client-Side invokes Client Stub Network connect to remote object Middle Tier
return results
return results
Skeleton invoke ServerSide Compo nent return results
34
05/05/12
G53ELC
A Taxonomy of EJBs
G53ELC
EJB
Entity Session
Bean managed
Container managed
stateless
stateful
05/05/12
G53ELC
35
Differences Between Beans
Session Beans Interact with clients Model business Logic Short-lived
Session Bean
Enterprise JavaBeans Container
G53ELC Entity Beans Represent persistent data Long-lived
Entity Bean
Clients
RDBMS
05/05/12
G53ELC
36
Session Bean (Stateful)
G53ELC Assigned to 1 client only Keeps info about a client ie has attributes for clients state Assigned to a client for lifetime Non-persistent Short-lived (client, timeout, server crash)
05/05/12
G53ELC
37
Session Bean (Stateless)
G53ELC
Many clients can access it Implements business logic One bean can service multiple clients (fast and efficient) Lifetime controlled by container No state across methods Each instance identical upon creation Short-lived
05/05/12 G53ELC 38
Insight Into Session Beans
Clients Using only Entity Beans G53ELC Client Using stateless Session Beans
EJB Server
05/05/12 G53ELC 39
Entity EJBs
G53ELC
Bean managed persistence (BMP)
developer writes JDBC code and SQL statements Container generates methods to read and write to the database dropped! Takes necessary information from the Deployment Descriptor
Container managed persistence (CMP)
05/05/12
G53ELC
40
EJB Architecture Diagram
G53ELC Client Home Interface Home Stub Remote Interface EJB Stub EJB Server EJB Container Home Interface EJB Home Remote Interface EJB Object Bean Class
05/05/12
G53ELC
41
A Stateless Session Bean
import javax.ejb.*; /** * A stateless session bean requesting that a * remote busines interface be generated for it. */ @Stateless @Remote public class HelloWorldBean { public String sayHello() { return "Hello World!!!"; } }
G53ELC
05/05/12
G53ELC
42
A Stateful Session Bean
import javax.ejb.*; @Stateful public class ShoppingCartBean implements ShoppingCart { private String customer; public void startToShop(String customer) { this.customer = customer; } public void addToCart(Item item) { System.out.println("Added item to cart... "); } @Remove public void finishShopping() { System.out.println("Shopping Done... "); } }
G53ELC
05/05/12
G53ELC
43
A Entity Java Bean
G53ELC
import javax.ejb.*; @Entity public class Order { private Long id; private int version; private int itemId; private int quantity; private Customer cust; @Id(generate=AUTO) public Long getId() { return id; } public void setId(Long id) { this.id = id; } @Version protected int getVersion() { return version; } protected void setVersion(int version) { this.version = version; } @Basic public int getItemId() { return itemId; } public void setItemId(int itemId) { this.itemId = itemId; } @Basic public int getQuantity() { return quantity; } public void setQuantity(int quantity) { this.quantity = quantity; } @ManyToOne public Customer getCustomer() { return cust; } public setCustomer(Customer cust) { this.cust = cust; } }
05/05/12
G53ELC
44
SQL and Entity beans
G53ELC Queries can be defined through the @NamedQuery annotation @NamedQuery ( name="findACustomers", queryString="SELECT c FROM Customer c WHERE c.name LIKE :custName" )
05/05/12
G53ELC
45
End of detour into Java!
G53ELC
05/05/12
G53ELC
46