The Spring PetClinic Application

Updated:21.OCT.2007Sam Brannen
30.JUN.2006Costin Leau
01.DEC.2004Ken Krebs
16.AUG.2003Ken Krebs

Introduction

The Spring Framework 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 Java EE 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 Java EE web application container that is compatible with the Servlet 2.4 and JSP 2.0 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.8.0 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 Log4jloggers.

Business Layer

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 the following data access technologies aided by infrastructure provided by Spring:

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. (See the 'jpetstore' sample application that ships with the full Spring Framework distribution for an example of using iBatis and Spring.)

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. Each persistence strategy in PetClinic is a different implementation of the Clinic interface. In each case, the Clinic implementation is fronted by a transactional proxy, configured via the @Transactional annotation, 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 via <tx:annotation-driven /> 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 Java EE 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.jdbc.object. These classes and the lower-level Spring classes that they use in the org.springframework.jdbc.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 respective domain object. This typically is done by extending one of the org.springframework.jdbc.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.

The JDBC implementation of the Clinic interface is org.springframework.samples.petclinic.jdbc.SimpleJdbcClinic, which uses Java 5 language features, org.springframework.jdbc.core.simple.SimpleJdbcTemplate, and org.springframework.jdbc.core.simple.SimpleJdbcInsert. It also takes advantage of classes like org.springframework.jdbc.core.namedparam.BeanPropertySqlParameterSource and org.springframework.jdbc.core.simple.ParameterizedBeanPropertyRowMapper which provide automatic mapping between JavaBean properties and JDBC parameters or query results. SimpleJdbcClinic is a rewrite of the AbstractJdbcClinic which was the base class for JDBC implementations of the Clinic interface for Spring 2.0.

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 3 Clinic Implementation

The Hibernate 3 implementation of the Clinic interface is org.springframework.samples.petclinic.hibernate.HibernateClinic. To simplify using Hibernate, Spring provides the org.springframework.orm.hibernate3.LocalSessionFactoryBean. The Hibernate configuration is provided by the file src/petclinic.hbm.xml.

Java Persistence API (JPA) Clinic Implementation

The JPA implementation of the Clinic interface is org.springframework.samples.petclinic.jpa.EntityManagerClinic, which is based on native JPA usage combined with Spring's @Repository and @Transactional annotations but otherwise has no dependencies on any Spring API's. To simplify JPA usage, Spring provides (among other classes) the org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean. The JPA configuration is provided by src/META-INF/orm.xml and src/META-INF/persistence.xml.

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 3 versions (1 per access strategy) of the PetClinic war/WEB-INF/applicationContext-*.xml file:

  1. A PropertyPlaceholderConfigurer, which is configured via <context:property-placeholder ... /> and 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 src/jdbc.properties).
  2. dataSource, which is a singleton bean that defines the implementation of the source of database connections used by the application.
  3. transactionManager, which is a singleton bean that defines the implementation of the transaction management strategy for the application.
  4. clinic, which is a singleton bean that defines the implementation of the Clinic interface that provides the primary Business Layer API of the application.

Presentation Layer

The Presentation Layer is implemented as a Java EE 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 definitions 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.

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.

ClinicController relies on RequestToViewNameTranslator to automatically infer the logical view name from the incoming request URL; whereas, all Form controllers in the PetClinic application return logical view names as Strings. These logical view names are then mapped to physical paths via the configured InternalResourceViewResolver (see the DispatcherServlet section above for further details). Logical view names that are prepended with "redirect:" will be resolved to instances of RedirectView, which simply redirects to another URL. The other resolved Views will be instances of JstlView, which provides some handy support for 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 a localized "welcome" message as well as localized form entry error messages in the default (i.e., English) and German properties files. See the "countries" sample application for a more detailed example of Spring's support for internationalization.

Presentation Layer classes

Logical Views & Implemented Use Cases

Java Server Pages

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 application 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 ".do" are handled by web application controllers. Static html pages ending in ".html", such as Javadoc, 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

Downloads

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 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 alternatively edit the file to select a port of your choosing. A useful database manager can be started 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 how to change the port the server uses.

MYSQL Setup (optional)

Add the PetClinic database to a running MySQL server by following the explicit instructions found in db/mysql/petclinic_db_setup_mysql.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 Java EE 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 either "hsqldb" or "mysql". 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 and database used for the webapp and for testing, you will need to edit the following files:
    • war/WEB-INF/applicationContext-*.xml: for configuring the DataSource in the webapp
    • src/jdbc.properties: for configuring JDBC connection settings for both the webapp and testing
    • build.properties: for running the "tests" target in Ant

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, generate Javadoc, 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.