The Spring Petclinic Application

Updated :
   
01-DEC-2004 - Ken Krebs
    16-AUG-2003
- Ken Krebs

Introduction

Spring is a collection of small, well-focused, loosely coupled Java frameworks that can be used independently or collectively to build industrial strength applications of many different types. The Petclinic sample application is designed to show how the Spring application frameworks can be used to build simple, but powerful database-oriented applications. It will demonstrate the use of Spring's core functionality:
The Spring frameworks provide a great deal of useful infrastructure to simplify the tasks faced by application developers. This infrastructure helps developers to create applications that are :
It is assumed that users of this tutorial will have a basic knowledge of object-oriented design, Java, Servlets, JSP, and relational databases. It also assumes a basic knowledge of the use of a J2EE web application container.

Since the purpose of the sample application is tutorial in nature, the implementation presented here will of course provide only a small subset of the functionality that would be needed by a real world version of a Petclinic application.

Petclinic Sample Application Requirements

The application requirement is for an information system that is accessible through a web browser. The users of the application are employees of the clinic who in the course of their work need to view and manage information regarding the veterinarians, the clients, and their pets. The sample application supports the following:

Use Cases:
Business Rules:
  1. An owner may not have multiple pets with the same case-insensitive name.

Petclinic Sample Application Design & Implementation

Server Technology
The sample application should be usable with any J2EE web application container that is compatible with the Servet 2.3 and JSP 1.2 specifications. Some of the deployment files provided are designed specifically for Apache Tomcat. These files specify container-supplied connection-pooled data sources. It is not necessary to use these files. The application has been configured by default to use a data source without connection pooling to simplify usage. Configuration details are provided in the Developer Instructions section. The view technologies that are to be used for rendering the application are Java Server Pages (JSP) along with the Java Standard Tag Library (JSTL).

Database Technology
The sample application uses a relational database for data storage. Support has been provided for a choice of 1 of 2 database selections, MySql or HypersonicSQL. HypersonicSQL version 1.7.2 is the default choice and a copy is provided with the application. It is possible to easily configure the application to use either database. Configuration details are provided in the Developer Instructions section.

Development Environment
A copy of the Spring runtime library jar file is provided with the sample application along with some of the other required jar files. The developer will need to obtain the following tools externally, all of which are freely available:
NOTE: The version numbers listed are those that were used in the development of the Petclinic application. Other versions of the same tools may or may not work.

Download links for the various tools needed are provided in the Developer Instructions section.

Petclinic Database
The following is an overview of the database schema used in Petclinic. Detailed field descriptions can be found in the "initDB.txt" SQL script files in the database-specific "db" sub-directories. All "id" key fields are of Java type int.

TABLE: owners
    PRIMARY KEY id

TABLE: types
    PRIMARY KEY id

TABLE: pets
    PRIMARY KEY id
    FOREIGN KEY type_id references the types table id field
    FOREIGN KEY owner_id references the owners table id field

TABLE: vets
    PRIMARY KEY id

TABLE: specialties
    PRIMARY KEY id

TABLE: vet_specialties- a link table for vets and their specialties
    FOREIGN KEY vet_id references the vets table id field
    FOREIGN KEY specialty_id references the specialties table id field

TABLE: visits
    PRIMARY KEY id
    FOREIGN KEY pet_id references the pets table id field


Directory Structure
d-- indicates a directory holding source code, configuration files, etc.
D-- indicates a directory that is created by the build script

d-- petclinic : the root directory of the project contains build related files
    d-- src : contains Java source code files and ORM configuration files
    d-- war : contains the web application resource files
        d-- html : contains tutorial files
        D-- docs : contains Javadoc files
        d-- web-inf : contains web application configuration files and application context files
              d-- jsp: contains Java Server Page files
              D-- lib: contains application dependencies
    d-- test : contains testing related Java source code files
    d-- db : contains database sql scripts and other related files/directories
        d-- hsqldb : contains files related to HSQL, contains scripts and a Tomcat context definition file
        d-- mysql : contains files related to MySQL, contains scripts and a Tomcat context definition file
    D-- .classes : contains compiled Java class files
    D-- .testclasses : contains compiled testing related Java class files
    D-- junit-reports : contains generated xml-formatted test reports
         D-- reports/html : contains generated html-formatted test reports
    D-- dist : contains packaged archives of files

Petclinic Application Design

Logging

Spring supports the use of the Apache Commons Logging API.This API provides the ability to use Java 1.4 loggers, the simple Commons loggers, and Apache Log4J loggers. Petclinic uses Log4J to provide sophisticated and configurable logging capabilities. The file, war/WEB-INF/log4j.properties configures the definition of Log4j loggers.

BusinessLayer

The Business Layer consists of a number of basic JavaBean classes representing the application domain objects and associated validation objects that are used by the Presentation Layer.The  validation objects used in Petclinic are all implementations of  the org.springframework.validation.Validator interface.


Business/Persistence Layer

Since the Petclinic application is all about database access and there is very little business logic in the application outside of that, there is no separation of the primary Business and Persistence Layer API's. While this design technique should not be used for an application with more complex business logic, it is acceptable here because all of the non-persistence related business rules have been implemented in business objects and have not leaked into the Persistence Layer. The most important facet of the design is that the Business and Persistence Layers are COMPLETELY independent of the Presentation Layer.

The Persistence Layer can be configured to use either HSQL or MySQL with any one of three strategies aided by infrastructure provided by Spring:
  1. JDBC
  2. Hibernate
  3. Apache OJB
NOTE: Spring also provides infrastructure for using other Object-Relational-Mapping frameworks such as  JDO and iBATIS SqlMaps but these are not demonstrated in Petclinic.

One of the key elements provided by Spring is the use of a common set of meaningful data access exceptions that can be used regardless of which database or access strategy is used. All of these exceptions derive from org.springframework.dao.DataAccessException. Since most exceptions encountered during database access are indicative of programming errors, DataAccessException is an abstract RuntimeException whose derivatives only need to be caught by application code to handle recoverable errors when it makes sense to do so. This greatly simplifies application code  compared to, for example, code using  JDBC directly where SqlExceptions must be caught and database specific error codes must be decoded. Examination of the Petclinic source code will show that the persistence-oriented code is completely focused on the relevant transfer of data to/from the referenced objects without extraneous error handling.

The high-level business/persistence API for Petclinic is the  org.springframework.samples.petclinic.Clinic interface. Spring provides several convenient abstract DaoSupport classes for each of the persistence strategies. Each persistence strategy in Petclinic is a different implementation of the Clinic interface that extends the respective DaoSupport class. In each case, the Clinic implementation is fronted by a transactional proxy that also implements Clinic. These objects are standard Java dynamic proxies which are created by an instance of  org.springframework.transaction.interceptor.TransactionProxyFactoryBean. These proxies are configured in the respective application context file and specify that all Clinic methods are run in a transactional context.The transaction managers used in Petclinic are all implementations of  the org.springframework.transaction.PlatformTransactionManager interface. All of the implementations are by default configured to use a local DataSource that will work in any environment through the use of an instance of  org.springframework.jdbc.datasource.DriverManagerDataSource. While this is appropriate for use in a demo or single user program,  a connection pooling DataSource, such as an instance of org.apache.commons.dbcp.BasicDataSource, is more appropriate for use in a multi-user application. Another alternative is to obtain one through the J2EE environment  using  an instance of org.springframework.jndi.JndiObjectFactoryBean.

JDBC Clinic Implementation
Spring provides a number of high-level database access convenience classes in the package org.springframework.jdcb.object. These classes and the lower-level Spring classes that they use in the org.springframework.jdcb.core package provide a higher level of abstraction for using JDBC that keeps the developer from having to correctly implement the handling of the checked SqlExceptions with ugly error-prone nested try-catch-finally blocks. Using the classes in this package allows the developer to focus efforts on the functionality being implemented rather than the mechanics of error handling. When using these classes, it is the responsibility of the developer to provide the SQL needed and to map the parameters to/from the repective domain object. This typically is done by extending one of the org.springframework.jdcb.object classes, initializing its SQL,  and overriding a method that takes care of the mapping. In this way, the developer gets to focus on implementing functionality rather than application plumbing. These classes also take care of closing connections to prevent hard to find resource leakage problems. It should be noted that instances of these classes are lightweight, reusable, and threadsafe.

All of these objects in Petclinic initialize the SQL in their constructors. SQL "Select" type queries are implemented by subclassing org.springframework.jdcb.object.MappingSqlQuery. These subclasses override the mapRow(ResultSet, int rowNum) method to extract data from the ResultSet returned to the framework by execution of the query. The framework calls this method once for every row in the ResultSet. SQL "Update" and "Insert" type queries are implemented by subclassing org.springframework.jdcb.object.SqlUpdate. These subclasses override or call an update(Object[]) method that places the domain object data into an Object array which is substituted into the appropriate SqlParameters of a PreparedStatement.

The primary JDBC implementation of the Clinic interface is org.springframework.samples.petclinic.jdbc.AbstractJdbcClinic. It defines and uses the following inner classes: The HSQL specific extension of AbstractJdbcClinic is org.springframework.samples.petclinic.petclinic.jdbc.HsqlClinic. It provides an HSQL implementation of the getIdentityQuery() method.

The MySQL specific extension of AbstractJdbcClinic is org.springframework.samples.petclinic.petclinic.jdbc.MysqlClinic. It provides an MySQL implementation of the getIdentityQuery() method.

The transaction manager used in the JDBC Clinic Implementation is an instance of  org.springframework.jdbc.datasource.DataSourceTransactionManager that can be used for local transactions.
 
Hibernate Clinic Implementation
The Hibernate implementation of the Clinic interface is org.springframework.samples.petclinic.hibernate.HibernateClinic. To simplify using Hibernate, Spring provides the org.springframework.orm.hibernate.LocalSessionFactoryBean. The Hibernate configuration is provided by the file  src/petclinic.hbm.xml.

Apache OJB Clinic Implementation
The Apache OJB implementation of the Clinic interface is org.springframework.samples.petclinic.ojb.PersistenceBrokerClinic. To simplify using OJB, Spring provides the org.springframework.orm.ojb.PersistenceBrokerTransactionManager. The Apache OJB configuration is provided by the files  src/OJB-repository.xml and src/OJB.properties.


ApplicationContext

A Spring org.springframework.context.ApplicationContext object provides a map of user-defined JavaBeans that specify either a singleton object or the initial construction of prototype instances. These beans constitute the Business/Persistence Layer of Petclinic.The following  beans are defined in all of the 3 versions (1 per access strategy) of the Petclinic applicationContext-???.xml file:
  1. propertyConfigurer is a singleton bean that replaces ${...} placeholders with values from a properties file, in this case, JDBC-related settings for the dataSource bean described below (see war/WEB-INF/jdbc.properties).
  2. dataSource is a singleton bean that defines the implementation of the source of database connections used by the application.
  3. clinicTarget is a singleton bean that defines the implementation of the Clinic interface that provides the primary Business Layer API of the application.
  4. transactionManager  is a singleton bean that defines the implementation of the transaction management strategy for the application.
  5. clinic is a singleton bean that provides the transactional proxy for the clinicTarget bean.

Presentation Layer

The Presentation Layer is implemented as a J2EE Web Application and provides a very thin and concise Model-View-Controller type user interface to the Business and Persistence Layers.

The Petclinic web application is configured via the following files:
Examine the comments provided in each of these files for a more in-depth understanding of the details of how the application is configured.

General
The files web.xml and log4j.properties specify the configuration of logging in the system:
Examination and study of these logging files will provide insight into the operation of the Spring framework and the application as well as valuable troubleshooting information should something not work correctly.

DispatcherServlet
The following beans are accessible to the DispatcherServlet and are defined in the Petclinic petclinic-servlet.xml file. This dispatcher uses these defintions to delegate actual display and form processing tasks to implementations of the Spring org.springframework.web.servlet.mvc.Controller interface. The DispatcherServlet acts as the main application Front Controller and is responsible for dispatching all requests to the appropriate Controller indirectly through a URL mapping handler. These Controllers are responsible for the mechanics of interaction with the user and ultimately delegate action to the Business/Persistence Layers. Controllers
Spring provides a number of useful MVC abstractions to developers of  J2EE web applications. The Controller interface specifies a single method, handleRequest(HttpServletRequest, HttpServletResponse) that must be provided by implementing classes to handle request processing. This method returns a org.springframework.web.servlet.mvc.ModelAndView to the DispatcherServlet for rendering. Spring provides several convenient implementations of the Controller interface that developers can use to simplify their task, the most significant of which are MultiActionController, SimpleFormController, and AbstractWizardFormController. AbstractWizardFormController is not used in Petclinic and is not discussed here. A MultiActionController is used to define a Controller with multiple handling methods the selection of which can be configured using a separate MethodNameResolver object. "FormControllers", including SimpleFormController, are used to process html forms and can automatically populate "command" objects with data supplied via request parameters and vice versa. SimpleFormController is part of a deep hierarchy of objects which is discussed here. Additional detail is avaliable in the Spring API Javadoc.
 

Views

The Controllers used by the dispatcher handle the work flow of the application. The actual display tasks are delegated by the Controllers to implementations of the Spring View interface. These View objects are themselves beans that can render a particular type of view. The handling Controller supplies the View with a data model to render. The data model is provided to the View as a Map of objects. Views are only responsible for rendering a display of the data model and performing any display logic that is particular to the type of View being rendered. Spring provides support for rendering many different types of views: JSP, XSLT, PDF, Velocity templates, Excel files, and others. By using a View mapping strategy, Spring supplies the developer with a great deal of flexibility in supporting easily configurable view substitution. Petclinic defines a number of View beans in the file, views.properties. 2 of these beans are instances of RedirectView which simply redirects to another URL. The other View beans are instances of JstlView which provides some handy support for supporting internationalization/localization in JSP pages that use JSTL.

Messages
The messages*.properties files are loaded from the classpath to provide localized messages for the supported languages. Petclinic supplies only a single localized message, "welcome" in the default, English, and German properties files respectively. See the "countries" sample application for a more detailed example of Spring's support for internationalization.

Presentation Layer classes

View Beans & Implemented Use Cases
JSP Pages
The following JSP's each display a form field and the bound error data for that field:

The following items should be noted regarding the web application implementation design:
  1. all JSP's are stored under /WEB-INF/jsp except for index.jsp which is the configured "welcome-file"
  2. The use of JSP technology in the appplication is not exposed to the user, i.e., the end user never sees a URL ending in ".jsp".
  3. By convention, all URL's in the application ending in ".htm" are handled by web application controllers. Static html pages ending in ".html", such as Javadocs, will be directly served to the end user.
  4. The results of all form entries are handled using browser round trip redirection to minimize possible end user confusion.
  5. All pages are extremely simple JSP implementations that focus only on providing the necessary functionality.
  6. References to Entity objects are passed around in the application by supplying the object's Id as a request parameter.

Testing


Ant Setup
Make sure that the Ant executable is in your command shell path. Ant will need to reference classes from JUnit and the database(s) of interest. Place a copy of any needed jar files in Ant's /lib directory, i.e.:
HSQL Setup
Create a new directory containing the a copy of the entire contents of the directory petclinic/db/hsqldb. The file petclinic.script is the data file that will be used by the server. It has been initialized with some sample data. Start a server on the standard port by executing server.sh(Unix) or server.bat (Windows) or alterrnatively edit the file to select a port of your choosing. A useful database manager can be started by  by executing manager.sh (Unix) or manager.bat (Windows). When the application opens, connect to the "HSQL Database Engine Server" using the default parameters. This tool can also be used to manage other databases. To use a different port, it will be necessary to change the Petclinic Database Setup. It may also be necessary to consult the HSQL documentation for instructions on to change the port the server uses.

MYSQL Setup (optional)
Add the Petclinic database to a running server by running the SQL script db/mysql/initDB.txt. Petclinic expects, by default to be able to access the server via the standard port 3306. To use a different port, it will be necessary to change the Petclinic Database Setup.

Petclinic Database Setup
To use a J2EE server supplied connection-pooled data source with Tomcat, it will be necessary to use and possibly edit the appropriate context definition file for the petclinic webapp. To use it, deploy a copy of the appropriate context definition file in Tomcat's webapps directory and restart the server. Consult the Tomcat log files if something goes wrong when starting either Tomcat or the Petclinic application. The context files are named petclinic_tomcat_*.xml, where * is a codename for the database. There is a context file supplied for each database in its respective directory. There is also a context file db/petclinic_tomcat_all.xml that will provide a JNDI connection-pooled datasource for all supported databases. Should you use this file, you must of course make sure that all the database servers are running when you restart Tomcat.

NOTES:
  1. Should you deploy one of the context files or define a context in Tomcat's server.xml, Tomcat will not automatically deploy the webapp from the petclinic.war file. The webapp will then need to be manually extracted to the target directory.
  2. The context files will also configure logging to supply a separate log file for the petclinic context. This will separate the container logging for petclinic from that of the other webapps. This should not be confused with the application log file provided through Log4j.
  3. An Ant script (db/build.xml ) has been provided that can be used to re-initialize either database. To select or configure the data source used for the webapp and for testing, you will need to edit the files:
Building the Petclinic Application
Open a command line shell and navigate to the directory containing Petclinic and execute "ant". This will display a list of the Ant targets that are available. Make sure the database is running and execute "ant all". This will run the Ant "all" target which will clean and compile everything, produce Javadocs, and execute the tests, including a live test using the database. The other Ant targets provide subsets of this functionality.

Deploying the Petclinic Application
Deploy the web application to the server in the usual way (see notes regarding database setup). If you need instructions for web application deployment, see the Tomcat documentation for details. The Web ARchive file is petclinic.war and can be found in the dist directory.

Using the Petclinic Application
Make sure the Petclinic web application is running and browse to http://localhost:8080/petclinic or check it out online.