PetClinic demonstrates the use of a Spring Boot with Spring MVC and Spring Data. The PetClinic has an old and varied history dating right back to the beginning of the Spring Framework. It started life as a demonstration of nearly all the common things that you could do with Spring, back when it was possible to conceive of such a demonstration. These days it is a very small slice of what you could achieve, but the community has a soft spot for it, so it's nice to see it still going after all this time, so we hope you enjoy it too.
You need Java 1.8 and git:
$ git clone https://github.com/spring-projects/spring-petclinic.git $ cd spring-petclinic $ ./mvnw spring-boot:run
You can then access petclinic here: http://localhost:8080/
The Spring Petclinic master branch in the main spring-projects GitHub org is the "canonical" implementation, currently based on Spring Boot and Thymeleaf. There are quite a few forks with different flavours of implementation in a special GitHub org spring-petclinic. If you have a special interest in a different technology stack that could be used to implement the Pet Clinic then please join the community there.
For posterity: here is the text of the old https://springframework.org/docs/petclinic.html. Thankfully, much of it is irrelevant or inaccurate now, but it might be an interesting historical document one day. A monument to all those who served in this vessel…
Updated: 21.OCT.2007 Sam Brannen
30.JUN.2006 Costin Leau
01.DEC.2004 Ken Krebs
16.AUG.2003 Ken Krebs
Note: This document covers the PetClinic sample application distributed with the Spring Framework 2.5 and earlier. With the introduction of Spring Framework 3.0 this sample application is no longer part of the distribution. The code is now maintained as part of a separate source repository for samples.
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:
JavaBeans based application configuration using Inversion-Of-Control Model-View-Controller web Presentation Layer Practical database access through JDBC, Hibernate, or Java Persistence API Application monitoring based on JMX Declarative Transaction Management using AOP Data Validation that supports but is not dependent on the Presentation Layer 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:
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.
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:
An owner may not have multiple pets with the same case-insensitive name. PetClinic Sample Application Design & Implementation
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).
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.
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.
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
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
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.
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.
org.springframework.samples.petclinic.Entityis a simple JavaBean superclass used for all persistable objects.
org.springframework.samples.petclinic.NamedEntityis an extension of Entity that adds a name property.
org.springframework.samples.petclinic.Specialtyis an extension of NamedEntity.
org.springframework.samples.petclinic.PetTypeis an extension of NamedEntity.
org.springframework.samples.petclinic.Personis an extension of Entity that provides a superclass for all objects that implement the notion of a person.
org.springframework.samples.petclinic.Vetis an extension of Person that implements a veterinarian. It holds a List of specialties that the Vet is capable of.
org.springframework.samples.petclinic.Owneris an extension of Person that implements a pet owner. It holds a List of pets owned.
org.springframework.samples.petclinic.Petis an extension of NamedEntity that implements a pet. It holds a List of visits made concerning the pet.
org.springframework.samples.petclinic.Visitis a simple JavaBean that implements the notion of a clinic visit for a pet.
org.springframework.samples.petclinic.util.EntityUtilsprovides utility methods for handling entities.
org.springframework.samples.petclinic.validation.OwnerValidatoris a Spring Validator that verifies correct data entry for the Add and Edit Owner forms.
org.springframework.samples.petclinic.validation.PetValidatoris a Spring Validator that verifies correct data entry for the Add and Edit Pet forms.
org.springframework.samples.petclinic.validation.VisitValidatoris a Spring Validator that verifies correct data entry for the AddVisit form.
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.
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.
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.
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.
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:
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.
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.
<context:component-scan ... />is used to autodetect the controllers in the org.springframework.samples.petclinic.web package, which are POJOs labeled with the @Controller annotation.
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.
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.
org.springframework.samples.petclinic.web.ClinicControlleris an annotation-driven, POJO MultiActionController that is used to handle simple display-oriented URLs.
org.springframework.samples.petclinic.web.FindOwnersFormis an annotation-driven, POJO Form controller that is used to search for Owners by last name.
org.springframework.samples.petclinic.web.AddOwnerFormis an annotation-driven, POJO Form controller that is used to add a new Owner to the system.
org.springframework.samples.petclinic.web.EditOwnerFormis an annotation-driven, POJO Form controller that is used to edit an existing Owner. A copy of the existing Owner is used for editing.
org.springframework.samples.petclinic.web.AddPetFormis an annotation-driven, POJO Form controller that is used to add a new Pet to an existing Owner.
org.springframework.samples.petclinic.web.EditPetFormis an annotation-driven, POJO Form controller that is used to edit an existing Pet. A copy of the existing Pet is used for editing.
org.springframework.samples.petclinic.web.AddVisitFormis an annotation-driven, POJO Form controller that is used to add a new Visit to an existing Pet.
The following items should be noted regarding the web application implementation design:
org.springframework.samples.petclinic.OwnerTestsis a simple JUnit 4 based TestCase that supports Business Rule #1.
org.springframework.samples.petclinic.AbstractClinicTestsis a JUnit 4 based TestCase requiring a live database connection that is used to confirm correct operation of the database access objects in the various implementations of the Clinic interface. "AbstractClinicTests-context.xml" declares a common javax.sql.DataSource. Subclasses specify additional context locations which declare a org.springframework.transaction.PlatformTransactionManager and a concrete implementation of Clinic.
AbstractClinicTestsextends AbstractTransactionalJUnit4SpringContextTests, one of the valuable testing support classes provided by the Spring TestContext Framework found in the org.springframework.test.context package. The annotation-driven configuration used here represents best practice for integration tests with Spring. Note, however, that AbstractTransactionalJUnit4SpringContextTests serves only as a convenience for extension. For example, if you do not wish for your test classes to be tied to a Spring-specific class hierarchy, you may configure your tests with annotations such as @ContextConfiguration, @TestExecutionListeners, @Transactional, etc.
AbstractClinicTests and its subclasses benefit from the following services provided by the Spring TestContext Framework:
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.:
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.
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.
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.
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.
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.
Make sure the PetClinic web application is running and browse to http://localhost:8080/petclinic.