Working for startups is always an interesting experience. Currently, I’m a software engineer at Velo Payments. If you’ve ever worked for a startup, you’ll quickly see that you get to wear many hats.

One of the hats I get to wear is the creation of of developer center (currently in the oven). In the very near future, Velo will be exposing a set of financial APIs to move money around the world.

Within the developer center, we hope to be introducing hundreds, thousands of consumers to our APIs.

API development is never an easy task. And evolving APIs is even more complicated.

Our use case raises a number of concerns:

  • How can we ensure we don’t inadvertantly release a breaking change to our APIs?
  • How do we communicate how to use our APIs?
  • How do we document our APIs?
  • How do we automate testing of our APIs?
  • Can we do all this and remain technology agnostic?

There is a plethora of tools available for our use. Yet none, is ‘just right’.

We clearly have a use case for Consumer Driven Contracts. To summarize the folks at ThoughtWorks:

Consumer-Driven Contracts are a pattern for evolving services. In Consumer-Driven Contracts, each consumer captures their expectations of the provider in a separate contract. All of these contracts are shared with the provider so they gain insight into the obligations they must fulfill for each individual client. The provider can create a test suite to validate these obligations. This lets them stay agile and make changes that do not affect any consumer, and pinpoint consumers that will be affected by a required change for deeper planning and discussion.

In a nutshell, a ‘contract’ can be looked at as a request / response pair. You give the API x, and can expect the API to return y. Contracts are a technique for defining API interactions.

Contracts however, do a very poor job of documenting APIs.

For our use case of releasing public APIs, we want a technology agnostic method of documenting our APIs. Currently, Open API is a clear leader in this domain.

In 2015, SmartBear donated the Swagger 2.0 specification to the Open API Initiative. This kicked off the formation of the Open API Initiative, a consortium of companies, including: 3Scale, Apigee, Capital One, Google, IBM, Intuit, Microsoft, PayPal, and Restlet.

In the summer of 2017, the Open API Initiative released the Open API 3.0 Specification. (Say adios to the name ‘Swagger’)

Open API 3.0 specifications can be written in JSON or YAML, and do an excellent job of documenting RESTful APIs.

The Open API Specification does not however, define API interactions.

The Open API 3.0 Specification does however, define extensions.

Through the use of Open API Specification Extensions, we can define Consumer Driven Contracts.

In this post I’m going to show you how to you can define Consumer Driven Contracts in the Open API 3.0 Specification for Spring Cloud Contract.

If you are not familiar with Spring Cloud Contract, please see my post showing how to use Spring Cloud Contract.

Spring Cloud Contract Groovy DSL

One of my initial concerns of Spring Cloud Contract was how you need to define the contracts in Groovy, and in a very Spring specific Groovy DSL. It’s not something that would be portable to other technologies.

Spring Cloud Contract YAML DSL

Here is the same contract expressed in YAML

Better. I like YAML, since its technology agnostic. Someone could port this DSL to a different technology stack.

Other Concerns about Spring Cloud Contract DSLs

Don’t Repeat Yourself

As Java developers, roughly since we learned how to write “Hello world”, Don’t repeat yourself, aka ‘DRY’ has been beaten in to our heads.

don't repeat yourselfLet’s say you have several conditions you wish to test for an endpoint. You’ll be duplicating a lot of code. Elements like the URL and Content-type will get repeated over and over. Clearly violating DRY!

And if you documented your API using Open API or Swagger, the DRY validations get even worse!

Consider the Spring Cloud Contract will define for each contract things like:

Spring Cloud Contract

  • Request / Response pairs
  • Paths
  • Parameters
  • Headers
  • Cookies
  • HTTP Methods
  • HTTP Status verbs

While the Open API Specification defines:

Open API

  • Paths
  • Parameters
  • Headers
  • Cookies
  • HTTP Methods
  • HTTP Status verbs
  • Request Schemas
  • Response Schemas

Consider the overlap:

Spring Cloud Contract / Open API

  • Paths
  • Parameters
  • Headers
  • Cookies
  • HTTP Methods
  • HTTP Status verbs
  • Request / Response Objects

Now we have DRY violations stacking up like flights going into Chicago O’hare!

What if I wish to refactor a URL path? Now I’m updating the controller source code, tests, contracts, and API documentation.

Thank god our IDEs have search and replace capabilities!

You Can’t Handle the Truth!

In my use case, the APIs under development will be public.

Thus, we do need solid API documentation. It does not need to be Open API. But it does need to be some type of friendly, human readable documentation.

As you start to define API attributes in contracts and in API documentation the question starts to become “what is the single source of truth for the API?”

One could argue it should be the API documentation.

Yet, just as easy to say it should be the consumer driven contracts.

Who’s API is it Anyways?

If we can’t determine the single source of truth for the API, who is the owner of the API?

Do the consumer driven contracts own the API? So the API documentation needs to conform to the contracts when there is a difference?

Or is the API definitively defined by the documentation? Thus, contracts must adhere to the API documentation.

Again a situation where valid arguments can be made for either one.

Contract First vs Code First vs Document First

Do you write contracts first?

Do you code first?

Do you write API documentation first?

We’re mostly developers, so code first, right???

What if we could write the API specification and contracts at the same time?

I know this whole area is subject to some very spirited debate. Not something I’ll be able to solve in this post.

Personally, I’m leaning more and more towards having the specification first, then contracts, then code.

Yes, there is tooling to generate Swagger / Open API from the Spring Source code. My biggest hesitation there is how do you prevent inadvertent breaking changes? Since your specification is generated from the source code, it will always be right. Even after you’ve broken a consumer.

Spring Cloud Contract Open API 3.0 Contract Converter

It is actually now possible to write Spring Cloud Contract definitions using Open API 3.0 with my Spring Cloud Contract Open API Contract Converter or SCC OA3 Converter for short.

Having the API Specification and API documentation in a single document, addresses many of the concerns above.

  • DRY violations are minimized!
  • A single source of truth for the API
  • The API is defined by the API Specification
  • Clear ownership of what the API is!

In a nutshell, the SCC OA3 Converter combines the SCC YAML DSL into OA3 extensions.

From the SCC OA3 Converter, you can expect:

  • Near 100% compatibility to the SCC YAML DSL (still testing edge cases)
  • The ability to define multiple contracts in OA3
  • Minimal violations of DRY
  • Having a single document which defines your API
  • The resulting OA3 Specification is 100% compatible with other OA3 tooling.

Open API 3.0 Consumer Driven Contracts Example

Spring Cloud Contract YAML Definitions

First lets explore two contracts written using using the existing YAML DSL of Spring Cloud Contract.

These two examples are from the YAML samples available in the Spring Cloud Contract GitHub Repository. I’m leaving the commenting in to help explain what each contract is doing.

Contract 1 – Should Mark Client as Fraud

Contract 2 – Should Mark Client as Not Fraud

It’s fairly clear what these two contracts are testing for.

Spring Cloud Contract Open API 3.0 Contracts

Here are the same contracts expressed using the Open API Specification.

Following the spirit of DRY, contract elements which can be derived from the Open API Specification, such as PATH are.

While elements which relate to defining the API interaction are defined in Open API Extensions.

Any property which starts with an ‘x-‘ is an Open API Extension object. As much as possible, the extension objects are modeled after the Spring Cloud Contract YAML DSL.

Open API 3.0 Contracts Example

This is the complete example. Following this example, I’ll break things down in depth.

Let’s break things down on how the contracts are defined in the Open API Specification.

Contract Definition

At a high level, contracts are defined using an extension on the Open API Operation Object.

In this snippet, I’m defining two contracts.

Open API Snippet

Both contracts will be applied against the path ‘/fraudcheck’ and the HTTP verb PUT.

The extension object ‘x-contracts’ is a list. The objects in the list are expected to have a contract ID. This ID property is important since it allows us to tie together properties of the contract defined in other sections of the Open API Specification.

Contract Request Definition

To define the request of the contract, the Open API Request Body Object is extended.

In this snippet, you can see how the Request Body is extended.

From the Open API Specification, we can determine the request should use ‘application/json’ for Content Type.

Then under the ‘x-contracts’ property, the request properties for two contracts are defined.

Open API Snippet

Contrast the above to this snippet from the Spring Cloud Contract YAML DSL.

Spring Cloud Contract YAML DSL Snippet

The body and matchers elements are the same.

While Content Type is not needed, since it is derived from the Open API Specification.

Contract Response Definition

To define the expected response for a given contract, the Open API Response Object is extended.

In the snippet below, the Open API Response object is the ‘200’ YAML property.

From the Open API properties, we can infer the expected response should have an HTTP status of 200, and the expected content type is ‘application/json’.

The response object is extended with the ‘x-contracts’ property.

In this example, you can see the expected response properties defined for two contracts.

Open API Snippet

Again, lets contrast this against the original Spring Cloud Contract YAML DSL example.

Here you can see we’re are expecting a HTTP 200 status and content type of ‘application/json’. (both defined in Open API Specification properties above)

And again the body and matchers elements remain the same.

Spring Cloud Contract YAML DSL Snippet

Next Steps

How to Define Your Own Contracts in Open API 3.0

If you’d like to try defining your own contracts for Spring Cloud Contract, please see my GitHub Repository. Here you will find complete directions on how to configure Maven and additional examples.

The above examples reference a common example used in the Spring Cloud Contract stand alone examples. You can find a complete example of a stand alone reference project here in GitHub. In this example, I literally copied the Java classes used in the Spring Cloud Contract YAML example, deleted the YAML contracts, and re-wrote them in Open API 3.0.

Help Wanted!

My Open API Contract converter is in its initial release. Spring Cloud Contract has a variety of examples of YAML contracts in their unit tests. I’d like to convert the remaining YAML contracts to Open API 3.0 contracts and write unit test for them. This is an area I’d love to get some help with.

If you’d like to contribute to this project, please see open issues here. I’ve also setup a Gitter room where you can communicate with me and others contributing to the project.

Atlassian’s Swagger Request Validator

Another tool I wish to explore is Atlassian’s Swagger Request Validator. They’ve added support for the Open API 3.0 specification just in the last few weeks. I want to see what additional assertions can be automated from properties defined in the API specification.

API Documentation for Humans

The Open API examples we’ve been looking at in this post are in YAML. YAML is great for computers, but not so great for humans.

The folks from Rebilly have open sourced their API documentation. They have a parser which consumes the Open API YAML to produce very rich API documentation using ReactJS. You can see an example here. I’m currently looking at using this tool document Velo’s public APIs.

Special Thanks

Special Thanks to Marcin Grzejszczak, one of the primary authors of Spring Cloud Contract. He’s been very helpful with Spring Cloud contract in general, and in guiding me in how to write the Open API 3.0 contract parser.

In Summary

Developing quality APIs is challenging. For the public API’s I’m supporting, using the Open API specification was an easy choice.

If I can provide an Open API specification of my APIs to others, now they have a tool they can leverage. I don’t know if my API consumers will be using Spring, .NET, Python, Ruby, or whatever.

Due to the popularity of Open API and Swagger there are a ton of tools to choose from.

Using the Open API Specification, I can:

  • Generate Server Side and Client Side stubs in roughly a gazillion different languages.
  • Create documentation in markdown
  • Insert request / response samples.
  • Provide code samples
  • Auto-generate code for Pact, Wiremock, RestAssured, Spring MockMVC via the Atlassian tools mentioned above.
  • Interact with the APIs via Swagger UI
  • Generate rich friendly API documentation like this Rebilly example. (Rebilly is just one example, there are many others)
  • And much more.

Seems like you can do more and more with Open API. You can even get a validator badge for GitHub. (OA3 support coming soon)

And now, you can define Consumer Driven Contracts for Spring Cloud Contract in Open API 3.0!


When you are developing Spring Boot applications with database interactions, you typically use Hibernate as the Object Relationship Mapping (ORM) tool.

Instead of directly coupling your code with Hibernate, often you’d rather use Spring Data JPA, a Spring Framework project.

Spring Data JPA makes implementation of the data access layer incredibly easy by abstracting most of the complexities involved in persisting data.

Often when you are working with Hibernate and Spring Data JPA, you will need to see what is happening under the hood. It is very helpful to see the actual SQL statements being generated by Hibernate.

Due to the nature of the abstractions offered by Hibernate and Spring Data JPA, its very easy to inadvertently create n+1 queries; which is VERY detrimental to the performance of your application.

In this post, I’ll share a tip on how to configure Hibernate and Spring Data JPA to log executed SQL statements and used bind parameters.

The Application

For the purpose of this post, I’ve created a simple Spring Boot application. In this application, we can perform CRUD operations on a Product entity.

Here is the  Product entity.


Below is a JUnit test class to save and retrieve products.

If you are new to JUnit, I’d suggest checking out my JUnit series of posts.


Activating Logging in Hibernate

To activate the logging of the executed SQL statements with Spring Boot, set the log level of the org.hibernate.SQL category to DEBUG.

If you wish to see the bind values, you can set the log level of org.hibernate.type.descriptor.sql to TRACE .

If you are new to logging frameworks, refer my series on Log4J2.

Here is the logging configuration in the application.properties.


Here is the log output showing the SQL statements generated by Hibernate.

Activating Logging with Spring Data JPA

If you are using Spring Data JPA with Hibernate as the persistence provider, add the following two lines in application.properties.

Here is the log output.


As you can see, its very easy to enable the logging of SQL statements with Spring Boot and Hibernate.

Being able to see what Hibernate is actually doing with the database is very important.

Often, when I’m working on a Spring Boot project, I will enable the SQL output just as a sanity check. I may believe everything is okay. But I have, in fact, found problems which I was unaware of by examining the SQL output.

, , ,

When developing Spring Boot applications, you need to tell the Spring Framework where to look for Spring components. Using component scan is one method of asking Spring to detect Spring managed components. Spring needs the information to locate and register all the Spring components with the application context when the application starts.

Spring can auto scan, detect, and instantiate components from pre-defined project packages. Spring can auto scan all classes annotated with the stereotype annotations @Component, @Controller, @Service, and @Repository

In this post, I will discuss how Spring component scanning works.

Sample Application

Let us create a simple Spring Boot application to understand how component scanning works in Spring.

We will start by writing few components.







Spring Framework 5
Click Here to Become a Spring Framework Guru!

The @SpringBootApplication Annotation

Spring needs to know which packages to scan for annotated components in order to add them to the IoC container. In a Spring Boot project, we typically set the main application class with the @SpringBootApplication annotation. Under the hood, @SpringBootApplication is a composition of the @Configuration, @ComponentScan, and @EnableAutoConfiguration annotations. With this default setting, Spring Boot will auto scan for components in the current package (containing the @SpringBoot main class) and its sub packages.

To know more about these annotations go through my Spring Framework Annotations post.

Note: It is recommended that you locate your main application class in a root package above the component classes of the application.

The code to create the main class and access components is this.


The output of running the main class is this.
Output of BlogPostsApplication.java class

As you can notice, all the classes in the sub packages of the main class BlogPostsApplication are auto scanned by Spring.

@ComponentScan – Identifying Base Packages

The @ComponentScan annotation is used with the @Configuration annotation to tell Spring the packages to scan for annotated components. @ComponentScan also used to specify base packages and base package classes using thebasePackageClasses or basePackages attributes of @ComponentScan.

The basePackageClasses attribute is a type-safe alternative to basePackages. When you specify basePackageClasses, Spring will scan the package (and subpackages) of the classes you specify. 

A Java class annotated with @ComponentScan with the basePackageClassesattribute is this.


The output on running the main class is this.
Output of BlogPostsApplicationWithComponentScan.java Class

The @ComponentScan annotation uses the basePackages attribute to specify three packages (and subpackages) that will be scanned by Spring. The annotation also uses the basePackageClasses attribute to declare the DemoBeanB1 class whose package Spring Boot should scan.

As demoBeanC is in a different package, Spring did not find it during component scanning.

Component Scanning Filters

You can configure component scanning by using different type filters that Spring provides.

By using filters, you can further narrow the set of candidate components from everything in basePackages to everything in the base packages that matches the given filter or filters.

Filters can be of two types: include and exclude filters. As their names suggest, include filters specify which types are eligible for component scanning, while exclude filters specify which types are not.

You can use the include and/or exclude filters with or without the default filter. To disable the default filter, set the useDefaultFilters element of the @ComponentScan annotation to false.

The code to disable the default filter is this.


In the preceding code, the value member defines the specific guru.springframework.blog.componentscan.example.demopackageA package to scan, while the useDefaultFilters member disables the default filter.

The output on running the main class is this.
Output of BlogPostsApplicationDisablingDefaultFilters.java Class

As you can notice, the class DemoBeanA in the package demopackageA is unavailable when the useDefaultFilters element of the @ComponentScan annotation is set to false.

Component Scanning Filter Types

Spring provides the FilterType enumeration for the type filters that may be used in conjunction with @ComponentScan.

The available FilterType values are:

  • FilterType.ANNOTATION: Include or exclude those classes with a stereotype annotation
  • FilterType.ASPECTJ: Include or exclude classes using an AspectJ type pattern expression
  • FilterType.ASSIGNABLE_TYPE: Include or exclude classes that extend or implement this class or interface
  • FilterType.REGEX: Include or exclude classes using a regular expression
  • FilterType.CUSTOM: Include or exclude classes using a custom implementation of the org.springframework.core.type.TypeFilter interface

Include Filters

With include filters, you can include certain classes to be scanned by Spring. To include assignable type, use the includeFilters element of the @ComponentScan annotation with FilterType. ASSIGNABLE_TYPE. Using this filter, you can instruct Spring to scan for classes that extends or implements the class or interface you specify.

The code to use the includeFilters element of @ComponentScan is this.


The output on running the main class is this.
Output of BlogPostsApplicationIncludeFilter.java Class

As shown in the preceding figure, Spring detected and used the demoBean3 component that extends demoBean2.

Spring Framework 5
Learn Spring Framework 5 with my Spring Framework 5: Beginner to Guru course!

Include Filters using Regex

You can use regular expressions to filter out components to be scanned by Spring. Use the includeFiltersnested annotation @ComponentScan.Filter type FilterType.REGEXto set a pattern.

The code to use an exclude filter based on regular expression is this.


The output of the following code snippet is this.
Output of BlogPostsApplicationFilterTypeRegex.java Class
As shown in the preceding figure, the classes whose names end with A, or 2 are detected by Spring.

Exclude Filters

The @ComponentScan annotation enables you to exclude those classes that you do not want to scan.

The code to use an exclude filter is this.


In this code, the nested annotation @ComponentScan.Filter is used to specify the filter type as FilterType.ASSIGNABLE_TYPE and the base class that should be excluded from scanning.

The output is this.
Output of using the FilterType.ASSIGNABLE_TYPE type

As you can see, the class DemoBeanB2 has been excluded from being scanned.


When using Spring Boot, most of the time the default auto scanning will work for your project. You only need to ensure that your @SpringBoot main class is at the base package of your package hierarchy. Spring Boot will automatically perform a component scan in the package of the Spring Boot main class and below.

One related annotation that I didn’t mention in this post is @EntityScan is more about JPA entity scanning rather than component scanning. The @EntityScan annotation, unlike @ComponentScan does not create beans. It only identifies which classes should be used by a specific persistence context.



I’m quickly becoming a fan of using CircleCI for CI builds. I’m finding that CircleCI is a very powerful platform. Recently, I configured CircleCI to build a Spring Boot Microservice. The microservice was generated by JHipster.

CircleCI is a online resource which uses Docker containers to run your CI builds. Since your build is running inside a Docker container, you can customize the container to support numerous different scenarios.

In this post, we’ll look at configuring CircleCI to build a Spring Boot Microservice generated by JHipster

Using CircleCI

CircleCI Account

CircleCI has a free tier which you can use for your CI builds. The free tier is limited to one running container at a time. Which is fine for many situations.

Signing up for CircleCI is crazy easy. All you need is a GitHub, BitBucket, or Google account.

Click here to get your free account.

Configuring CircleCI to Build JHipster Projects

JHipster Microservice

In this example, I’m using a Spring Boot microservice generated by JHipster.

My example application is a VERY basic example. I have not added any domains.

The focus of this post is on CI builds, not building microservices.

You can get the complete source code for this blog post here on GitHub.

CircleCI Build Config File

To build your project, CircleCI will look in the project root for the directory .circleci. The CircleCI build file is a YAML file named config.yml .

CircleCI has very powerful build capabilities. I cannot cove everything in this post. But, you can Click here to explore the capabilities found in CircleCI 2.0.

As Spring Framework Developers, it’s likely we will be using Maven or Gradle for our build tools. (I hope none of you are using Ant!)

Below are example build files for Maven and Gradle provided by CircleCI.

Maven CircleCI config.yml Example

Gradle CircleCI config.yml Example

Installing NodeJS

If your JHipster project has a UI component, you will need to install NodeJS and Yarn for the build process.

Adding these commands to the ‘steps’ section of your CircleCI build configuration will install NodeJS into the docker container running your build.

Installing Yarn

JHipster also uses Yarn for dependency management of UI components.

You can install Yarn by adding the following steps to your CircleCI build configuration.

Custom Docker Images

CircleCI does provide a number of pre-built images you can use for your builds.

In this example, I’m using an image with Java pre-installed.

It does not have NodeJS or Yarn pre-installed.

Above, I’m showing you how to install NodeJS and Yarn into your build container.

If I needed to build a lot of JHipster projects, I probably would develop my own custom Docker image for the builds.

In my custom image, I would pre-install NodeJS and Yarn.

Comment below if you would like to see a future blog post on how to setup a custom Docker image like this!

Building A Docker Image with CircleCI

You can also use CircleCI to build docker images to hold your Spring Boot microservice.

Of course, JHipster out of the box gives us the tools to build the Docker image.

CircleCI gives us the ability to leverage a remote Docker service to support Docker commands from within our build container.

To build a Docker Image of our Spring Boot microservice, we need to add two steps to our build configuration.

  1. Setup the Remote Docker connection to our build container.
  2. Run the build command for Maven / Gradle to build the Docker Image.

Here is an example configuration for using Gradle to create the Docker Image:

Complete CircleCI Build File

Here is the complete CircleCI Build file for my Spring Boot Microservice.


Memory Errors in CircleCI

In setting up some of my builds for JHipster, I ran into a intermittent build failures.

Here is the error I was seeing:

The exit value of 137 indicates the Java process was getting terminated by the operating system. Effectively the JVM was consuming too much memory. Then Docker was killing the container.

Some builds would work, some would fail.

I worked on this issue several hours and learned a lot about Gradle and JVM memory management.

Gradle Daemon for CI Builds

For CI Builds, the Gradle team recommends disabling the Gradle daemon. You can do this as follows:


JVM Memory Settings

You can also configure JVM memory settings via the Gradle properties file.

The above configuration did not help me.

Gradle seems to be launching another JVM process to execute tests in, and that JVM process does not seem to honor the memory arguments set in org.gradle.jvmargs or via environment variables.

However, what did work for me, was to configure the test task via build.gradle.

I added the following to the build configuration generated by JHipster:


Note: MaxPermSize has been deprecated from Java 8 and above. See this link.

Once I limited the JVM memory consumption, my builds became stable.

The JVM was likely failing due to how Java works with Docker. The JVM ‘sees’ memory for the entire host system, and does not recognize the memory limitations of the Docker container. See this post for additional details.

This issue is going to get better in future releases of Java. It has been addressed in Java 9 and backported to Java 8.



The Java Programming language provided support for Annotations from Java 5.0. Leading Java frameworks were quick to adopt annotations and the Spring Framework started using annotations from the release 2.5. Due to the way they are defined, annotations provide a lot of context in their declaration.

Prior to annotations, the behavior of the Spring Framework was largely controlled through XML configuration. Today, the use of annotations provide us tremendous capabilities in how we configure the behaviours of the Spring Framework.

In this post, we’ll take a look at the annotations available in the Spring Framework.

Core Spring Framework Annotations


This annotation is applied on bean setter methods. Consider a scenario where you need to enforce a required property. The @Required annotation indicates that the affected bean must be populated at configuration time with the required property. Otherwise an exception of type BeanInitializationException is thrown.


This annotation is applied on fields, setter methods, and constructors. The @Autowired annotation injects object dependency implicitly.

When you use @Autowired on fields and pass the values for the fields using the property name, Spring will automatically assign the fields with the passed values.

You can even use @Autowired  on private properties, as shown below. (This is a very poor practice though!)

When you use @Autowired on setter methods, Spring tries to perform the by Type autowiring on the method. You are instructing Spring that it should initiate this property using setter method where you can add your custom code, like initializing any other property with this property.

Consider a scenario where you need instance of class A, but you do not store A in the field of the class. You just use A to obtain instance of B, and you are storing B in this field. In this case setter method autowiring will better suite you. You will not have class level unused fields.

When you use @Autowired on a constructor, constructor injection happens at the time of object creation. It indicates the constructor to autowire when used as a bean. One thing to note here is that only one constructor of any bean class can carry the @Autowired annotation.

NOTE: As of Spring 4.3, @Autowired  became optional on classes with a single constructor. In the above example, Spring would still inject an instance of the Person  class if you omitted the @Autowired  annotation.


This annotation is used along with @Autowired annotation. When you need more control of the dependency injection process, @Qualifier can be used. @Qualifier can be specified on individual constructor arguments or method parameters. This annotation is used to avoid confusion which occurs when you create more than one bean of the same type and want to wire only one of them with a property.

Consider an example where an interface BeanInterface is implemented by two beans BeanB1 and BeanB2.

Now if BeanA autowires this interface, Spring will not know which one of the two implementations to inject.
One solution to this problem is the use of the @Qualifier annotation.

With the @Qualifier annotation added, Spring will now know which bean to autowire where beanB2 is the name of BeanB2.

Spring Framework 5
Learn the Spring Framework with my Spring Framework 5 – Beginner to Guru Course!


This annotation is used on classes which define beans. @Configuration is an analog for XML configuration file – it is configuration using Java class. Java class annotated with @Configuration is a configuration by itself and will have methods to instantiate and configure the dependencies.

Here is an example:


This annotation is used with @Configuration annotation to allow Spring to know the packages to scan for annotated components. @ComponentScan is also used to specify base packages using basePackageClasses or basePackage attributes to scan. If specific packages are not defined, scanning will occur from the package of the class that declares this annotation.

Checkout this post for an in depth look at the Component Scan annotation.


This annotation is used at the method level. @Bean annotation works with @Configuration to create Spring beans. As mentioned earlier, @Configuration will have methods to instantiate and configure dependencies. Such methods will be annotated with @Bean. The method annotated with this annotation works as bean ID and it creates and returns the actual bean.

Here is an example:


This annotation is used on component classes. By default all autowired dependencies are created and configured at startup. But if you want to initialize a bean lazily, you can use @Lazy annotation over the class. This means that the bean will be created and initialized only when it is first requested for. You can also use this annotation on @Configuration classes. This indicates that all @Bean methods within that @Configuration should be lazily initialized.


This annotation is used at the field, constructor parameter, and method parameter level. The @Value annotation indicates a default value expression for the field or parameter to initialize the property with. As the @Autowired annotation tells Spring to inject object into another when it loads your application context, you can also use @Value annotation to inject values from a property file into a bean’s attribute. It supports both #{...} and ${...} placeholders.

Spring Framework Stereotype Annotations


This annotation is used on classes to indicate a Spring component. The @Component annotation marks the Java class as a bean or say component so that the component-scanning mechanism of Spring can add into the application context.


The @Controller  annotation is used to indicate the class is a Spring controller. This annotation can be used to identify controllers for Spring MVC or Spring WebFlux.


This annotation is used on a class. The @Service marks a Java class that performs some service, such as execute business logic, perform calculations and call external APIs. This annotation is a specialized form of the @Component annotation intended to be used in the service layer.


This annotation is used on Java classes which directly access the database. The @Repository annotation works as marker for any class that fulfills the role of repository or Data Access Object.

This annotation has a automatic translation feature. For example, when an exception occurs in the @Repository there is a handler for that exception and there is no need to add a try catch block.

Spring Boot Annotations


This annotation is usually placed on the main application class. The @EnableAutoConfiguration annotation implicitly defines a base “search package”. This annotation tells Spring Boot to start adding beans based on classpath settings, other beans, and various property settings.


This annotation is used on the application class while setting up a Spring Boot project. The class that is annotated with the @SpringBootApplication must be kept in the base package. The one thing that the @SpringBootApplication does is a component scan. But it will scan only its sub-packages. As an example, if you put the class annotated with @SpringBootApplication in com.example then @SpringBootApplication will scan all its sub-packages, such as com.example.a, com.example.b, and com.example.a.x.

The @SpringBootApplication is a convenient annotation that adds all the following:

  • @Configuration
  • @EnableAutoConfiguration
  • @ComponentScan

Spring MVC and REST Annotations


This annotation is used on Java classes that play the role of controller in your application. The @Controller annotation allows autodetection of component classes in the classpath and auto-registering bean definitions for them. To enable autodetection of such annotated controllers, you can add component scanning to your configuration. The Java class annotated with @Controller is capable of handling multiple request mappings.

This annotation can be used with Spring MVC and Spring WebFlux.


This annotation is used both at class and method level. The @RequestMapping annotation is used to map web requests onto specific handler classes and handler methods. When @RequestMapping is used on class level it creates a base URI for which the controller will be used. When this annotation is used on methods it will give you the URI on which the handler methods will be executed. From this you can infer that the class level request mapping will remain the same whereas each handler method will have their own request mapping.

Sometimes you may want to perform different operations based on the HTTP method used, even though the request URI may remain the same. In such situations, you can use the method attribute of @RequestMapping with an HTTP method value to narrow down the HTTP methods in order to invoke the methods of your class.

Here is a basic example on how a controller along with request mappings work:

In this example only GET requests to /welcome is handled by the welcomeAll() method.

This annotation also can be used with Spring MVC and Spring WebFlux.

The @RequestMapping  annotation is very versatile. Please see my in depth post on Request Mapping bere.


This annotation is used at method parameter level. @CookieValue is used as argument of request mapping method. The HTTP cookie is bound to the @CookieValue parameter for a given cookie name. This annotation is used in the method annotated with @RequestMapping.
Let us consider that the following cookie value is received with a http request:


To get the value of the cookie, use @CookieValue like this:


This annotation is used both at class and method level to enable cross origin requests. In many cases the host that serves JavaScript will be different from the host that serves the data. In such a case Cross Origin Resource Sharing (CORS) enables cross-domain communication. To enable this communication you just need to add the @CrossOrigin annotation.

By default the @CrossOrigin annotation allows all origin, all headers, the HTTP methods specified in the @RequestMapping annotation and maxAge of 30 min. You can customize the behavior by specifying the corresponding attribute values.

An example to use @CrossOrigin at both controller and handler method levels is this.

In this example, both getExample() and getNote() methods will have a maxAge of 3600 seconds. Also, getExample() will only allow cross-origin requests from http://example.com, while getNote() will allow cross-origin requests from all hosts.

Composed @RequestMapping Variants

Spring framework 4.3 introduced the following method-level variants of @RequestMapping annotation to better express the semantics of the annotated methods. Using these annotations have become the standard ways of defining the endpoints. They act as wrapper to @RequestMapping.

These annotations can be used with Spring MVC and Spring WebFlux.


This annotation is used for mapping HTTP GET requests onto specific handler methods. @GetMapping is a composed annotation that acts as a shortcut for @RequestMapping(method = RequestMethod.GET)


This annotation is used for mapping HTTP POST requests onto specific handler methods. @PostMapping is a composed annotation that acts as a shortcut for @RequestMapping(method = RequestMethod.POST)


This annotation is used for mapping HTTP PUT requests onto specific handler methods. @PutMapping is a composed annotation that acts as a shortcut for @RequestMapping(method = RequestMethod.PUT)


This annotation is used for mapping HTTP PATCH requests onto specific handler methods. @PatchMapping is a composed annotation that acts as a shortcut for @RequestMapping(method = RequestMethod.PATCH)


This annotation is used for mapping HTTP DELETE requests onto specific handler methods. @DeleteMapping is a composed annotation that acts as a shortcut for @RequestMapping(method = RequestMethod.DELETE)


This annotation is used at method levels to handle exception at the controller level. The @ExceptionHandler annotation is used to define the class of exception it will catch. You can use this annotation on methods that should be invoked to handle an exception. The @ExceptionHandler values can be set to an array of Exception types. If an exception is thrown that matches one of the types in the list, then the method annotated with matching @ExceptionHandler will be invoked.


This annotation is a method level annotation that plays the role of identifying the methods which initialize the WebDataBinder - a DataBinder that binds the request parameter to JavaBean objects. To customise request parameter data binding , you can use @InitBinder annotated methods within our controller. The methods annotated with @InitBinder all argument types that handler methods support.
The @InitBinder annotated methods will get called for each HTTP request if you don’t specify the value element of this annotation. The value element can be a single or multiple form names or request parameters that the init binder method is applied to.

@Mappings and @Mapping

This annotation is used on fields. The @Mapping annotation is a meta annotation that indicates a web mapping annotation. When mapping different field names, you need to configure the source field to its target field and to do that you have to add the @Mappings annotation. This annotation accepts an array of @Mapping having the source and the target fields.


This annotation is used to annotate request handler method arguments so that Spring can inject the relevant bits of matrix URI. Matrix variables can appear on any segment each separated by a semicolon. If a URL contains matrix variables, the request mapping pattern must represent them with a URI template. The @MatrixVariable annotation ensures that the request is matched with the correct matrix variables of the URI.


This annotation is used to annotate request handler method arguments. The @RequestMapping annotation can be used to handle dynamic changes in the URI where certain URI value acts as a parameter. You can specify this parameter using a regular expression. The @PathVariable annotation can be used declare this parameter.


This annotation is used to bind the request attribute to a handler method parameter. Spring retrieves the named attributes value to populate the parameter annotated with @RequestAttribute. While the @RequestParam annotation is used bind the parameter values from query string, the @RequestAttribute is used to access the objects which have been populated on the server side.


This annotation is used to annotate request handler method arguments. The @RequestBody annotation indicates that a method parameter should be bound to the value of the HTTP request body. The HttpMessageConveter is responsible for converting from the HTTP request message to object.


This annotation is used to annotate request handler method arguments. The @RequestHeader annotation is used to map controller parameter to request header value. When Spring maps the request, @RequestHeader checks the header with the name specified within the annotation and binds its value to the handler method parameter. This annotation helps you to get the header details within the controller class.


This annotation is used to annotate request handler method arguments. Sometimes you get the parameters in the request URL, mostly in GET requests. In that case, along with the @RequestMapping annotation you can use the @RequestParam annotation to retrieve the URL parameter and map it to the method argument. The @RequestParam annotation is used to bind request parameters to a method parameter in your controller.


This annotation is used to annotate request handler method arguments. The @RequestPart annotation can be used instead of @RequestParam to get the content of a specific multipart and bind to the method argument annotated with @RequestPart. This annotation takes into consideration the “Content-Type” header in the multipart(request part).


This annotation is used to annotate request handler methods. The @ResponseBody annotation is similar to the @RequestBody annotation. The @ResponseBody annotation indicates that the result type should be written straight in the response body in whatever format you specify like JSON or XML. Spring converts the returned object into a response body by using the HttpMessageConveter.


This annotation is used on methods and exception classes. @ResponseStatus marks a method or exception class with a status code and a reason that must be returned. When the handler method is invoked the status code is set to the HTTP response which overrides the status information provided by any other means. A controller class can also be annotated with @ResponseStatus which is then inherited by all @RequestMapping methods.


This annotation is applied at the class level. As explained earlier, for each controller you can use @ExceptionHandler on a method that will be called when a given exception occurs. But this handles only those exception that occur within the controller in which it is defined. To overcome this problem you can now use the @ControllerAdvice annotation. This annotation is used to define @ExceptionHandler, @InitBinder and @ModelAttribute methods that apply to all @RequestMapping methods. Thus if you define the @ExceptionHandler annotation on a method in @ControllerAdvice class, it will be applied to all the controllers.


This annotation is used at the class level. The @RestController annotation marks the class as a controller where every method returns a domain object instead of a view. By annotating a class with this annotation you no longer need to add @ResponseBody to all the RequestMapping method. It means that you no more use view-resolvers or send html in response. You just send the domain object as HTTP response in the format that is understood by the consumers like JSON.

@RestController  is a convenience annotation which combines @Controller  and @ResponseBody .


This annotation is applied on Java classes. @RestControllerAdvice is a convenience annotation which combines  @ControllerAdvice and @ResponseBody. This annotation is used along with the @ExceptionHandler annotation to handle exceptions that occur within the controller.


This annotation is used at method parameter level. The @SessionAttribute annotation is used to bind the method parameter to a session attribute. This annotation provides a convenient access to the existing or permanent session attributes.


This annotation is applied at type level for a specific handler. The @SessionAtrributes annotation is used when you want to add a JavaBean object into a session. This is used when you want to keep the object in session for short lived. @SessionAttributes is used in conjunction with @ModelAttribute.
Consider this example.

The @ModelAttribute name is assigned to the @SessionAttributes as value. The @SessionAttributes has two elements. The value element is the name of the session in the model and the types element is the type of session attributes in the model.

Spring Cloud Annotations


This annotation is used at the class level. When developing a project with a number of services, you need to have a centralized and straightforward manner to configure and retrieve the configurations about all the services that you are going to develop. One advantage of using a centralized config server is that you don’t need to carry the burden of remembering where each configuration is distributed across multiple and distributed components.

You can use Spring cloud’s @EnableConfigServer annotation to start a config server that the other applications can talk to.


This annotation is applied to Java classes. One problem that you may encounter while decomposing your application into microservices is that, it becomes difficult for every service to know the address of every other service it depends on. There comes the discovery service which is responsible for tracking the locations of all other microservices.
Netflix’s Eureka is an implementation of a discovery server and integration is provided by Spring Boot. Spring Boot has made it easy to design a Eureka Server by just annotating the entry class with @EnableEurekaServer.


This annotation is applied to Java classes. In order to tell any application to register itself with Eureka you just need to add the @EnableDiscoveryClientannotation to the application entry point. The application that’s now registered with Eureka uses the Spring Cloud Discovery Client abstraction to interrogate the registry for its own host and port.


This annotation is applied on Java classes that can act as the circuit breaker. The circuit breaker pattern can allow a micro service continue working when a related service fails, preventing the failure from cascading. This also gives the failed service a time to recover.

The class annotated with @EnableCircuitBreaker will monitor, open, and close the circuit breaker.


This annotation is used at the method level. Netflix’s Hystrix library provides the implementation of Circuit Breaker pattern. When you apply the circuit breaker to a method, Hystrix watches for the failures of the method. Once failures build up to a threshold, Hystrix opens the circuit so that the subsequent calls also fail. Now Hystrix redirects calls to the method and they are passed to the specified fallback methods.
Hystrix looks for any method annotated with the @HystrixCommand annotation and wraps it into a proxy connected to a circuit breaker so that Hystrix can monitor it.

Consider the following example:

Here @HystrixCommand is applied to the original method bookList(). The @HystrixCommand annotation has newList as the fallback method. So for some reason if Hystrix opens the circuit on bookList(), you will have a placeholder book list ready for the users.

Spring Framework 5
Learn Spring Framework 5 with my Spring Framework 5: Beginner to Guru course!

Spring Framework DataAccess Annotations


This annotation is placed before an interface definition, a method on an interface, a class definition, or a public method on a class. The mere presence of @Transactional is not enough to activate the transactional behaviour. The @Transactional is simply a metadata that can be consumed by some runtime infrastructure. This infrastructure uses the metadata to configure the appropriate beans with transactional behaviour.

The annotation further supports configuration like:

  • The Propagation type of the transaction
  • The Isolation level of the transaction
  • A timeout for the operation wrapped by the transaction
  • A read only flag - a hint for the persistence provider that the transaction must be read only
    The rollback rules for the transaction

Cache-Based Annotations


This annotation is used on methods. The simplest way of enabling the cache behaviour for a method is to annotate it with @Cacheable and parameterize it with the name of the cache where the results would be stored.

In the snippet above , the method getAddress is associated with the cache named addresses. Each time the method is called, the cache is checked to see whether the invocation has been already executed and does not have to be repeated.


This annotation is used on methods. Whenever you need to update the cache without interfering the method execution, you can use the @CachePut annotation. That is, the method will always be executed and the result cached.

Using @CachePut and @Cacheable on the same method is strongly discouraged as the former forces the execution in order to execute a cache update, the latter causes the method execution to be skipped by using the cache.


This annotation is used on methods. It is not that you always want to populate the cache with more and more data. Sometimes you may want remove some cache data so that you can populate the cache with some fresh values. In such a case use the @CacheEvict annotation.

Here an additional element allEntries is used along with the cache name to be emptied. It is set to true so that it clears all values and prepares to hold new data.


This annotation is a class level annotation. The @CacheConfig annotation helps to streamline some of the cache information at one place. Placing this annotation on a class does not turn on any caching operation. This allows you to store the cache configuration at the class level so that you don’t have declare things multiple times.

Task Execution and Scheduling Annotations


This annotation is a method level annotation. The @Scheduled annotation is used on methods along with the trigger metadata. A method with @Scheduled should have void return type and should not accept any parameters.

There are different ways of using the @Scheduled annotation:

In this case, the duration between the end of last execution and the start of next execution is fixed. The tasks always wait until the previous one is finished.

In this case, the beginning of the task execution does not wait for the completion of the previous execution.

The task gets executed initially with a delay and then continues with the specified fixed rate.


This annotation is used on methods to execute each method in a separate thread. The @Async annotation is provided on a method so that the invocation of that method will occur asynchronously. Unlike methods annotated with @Scheduled, the methods annotated with @Asynccan take arguments. They will be invoked in the normal way by callers at runtime rather than by a scheduled task.

@Async can be used with both void return type methods and the methods that return a value. However methods with return value must have a Future typed return values.

Spring Framework Testing Annotations


This annotation is a class level annotation. The @BootstrapWith annotation is used to configure how the Spring TestContext Framework is bootstrapped. This annotation is used as a metadata to create custom composed annotations and reduce the configuration duplication in a test suite.


This annotation is a class level annotation that defines a metadata used to determine which configuration files to use to the load the ApplicationContext for your test. More specifically @ContextConfiguration declares the annotated classes that will be used to load the context. You can also tell Spring where to locate for the file.
@ContextConfiguration(locations={"example/test-context.xml", loader = Custom ContextLoader.class})


This annotation is a class level annotation. The @WebAppConfiguration is used to declare that the ApplicationContext loaded for an integration test should be a WebApplicationContext. This annotation is used to create the web version of the application context. It is important to note that this annotation must be used with the @ContextConfiguration annotation.The default path to the root of the web application is src/main/webapp. You can override it by passing a different path to the <span class="theme:classic lang:default decode:true crayon-inline">@WebAppConfiguration.


This annotation is used on methods. The @Timed annotation indicates that the annotated test method must finish its execution at the specified time period(in milliseconds). If the execution exceeds the specified time in the annotation, the test fails.

In this example, the test will fail if it exceeds 10 seconds of execution.


This annotation is used on test methods. If you want to run a test method several times in a row automatically, you can use the @Repeat annotation. The number of times that test method is to be executed is specified in the annotation.

In this example, the test will be executed 10 times.


This annotation can be used as both class-level or method-level annotation. After execution of a test method, the transaction of the transactional test method can be committed using the @Commit annotation. This annotation explicitly conveys the intent of the code. When used at the class level, this annotation defines the commit for all test methods within the class. When declared as a method level annotation @Commit specifies the commit for specific test methods overriding the class level commit.


This annotation can be used as both class-level and method-level annotation. The @RollBack annotation indicates whether the transaction of a transactional test method must be rolled back after the test completes its execution. If this true @Rollback(true), the transaction is rolled back. Otherwise, the transaction is committed. @Commit is used instead of @RollBack(false).

When used at the class level, this annotation defines the rollback for all test methods within the class.

When declared as a method level annotation @RollBack specifies the rollback for specific test methods overriding the class level rollback semantics.


This annotation is used as both class-level and method-level annotation. @DirtiesContext indicates that the Spring ApplicationContext has been modified or corrupted in some manner and it should be closed. This will trigger the context reloading before execution of next test. The ApplicationContext is marked as dirty before or after any such annotated method as well as before or after current test class.

The @DirtiesContext annotation supports BEFORE_METHOD, BEFORE_CLASS, and BEFORE_EACH_TEST_METHOD modes for closing the ApplicationContext before a test.

NOTE: Avoid overusing this annotation. It is an expensive operation and if abused, it can really slow down your test suite.


This annotation is used to annotate void methods in the test class. @BeforeTransaction annotated methods indicate that they should be executed before any transaction starts executing. That means the method annotated with @BeforeTransaction must be executed before any method annotated with @Transactional.


This annotation is used to annotate void methods in the test class. @AfterTransaction annotated methods indicate that they should be executed after a transaction ends for test methods. That means the method annotated with @AfterTransaction must be executed after the method annotated with @Transactional.


This annotation can be declared on a test class or test method to run SQL scripts against a database. The @Sql annotation configures the resource path to SQL scripts that should be executed against a given database either before or after an integration test method. When @Sql is used at the method level it will override any @Sql defined in at class level.


This annotation is used along with the @Sql annotation. The @SqlConfig annotation defines the metadata that is used to determine how to parse and execute SQL scripts configured via the @Sql annotation. When used at the class-level, this annotation serves as global configuration for all SQL scripts within the test class. But when used directly with the config attribute of @Sql, @SqlConfig serves as a local configuration for SQL scripts declared.


This annotation is used on methods. The @SqlGroup annotation is a container annotation that can hold several @Sql annotations. This annotation can declare nested @Sql annotations.
In addition, @SqlGroup is used as a meta-annotation to create custom composed annotations. This annotation can also be used along with repeatable annotations, where @Sql can be declared several times on the same method or class.


This annotation is used to start the Spring context for integration tests. This will bring up the full autoconfigruation context.


The @DataJpaTest  annotation will only provide the autoconfiguration required to test Spring Data JPA using an in-memory database such as H2.

This annotation is used instead of @SpringBootTest


The @DataMongoTest  will provide a minimal autoconfiguration and an embedded MongoDB for running integration tests with Spring Data MongoDB.


The @WebMVCTest will bring up a mock servlet context for testing the MVC layer. Services and components are not loaded into the context. To provide these dependencies for testing, the @MockBean annotation is typically used.


The @AutoConfigureMockMVC  annotation works very similar to the @WebMVCTest  annotation, but the full Spring Boot context is started.


Creates and injects a Mockito Mock for the given dependency.


Will limit the auto configuration of Spring Boot to components relevant to processing JSON.

This annotation will also autoconfigure an instance of JacksonTester or GsonTester.


Class level annotation used to specify property sources for the test class.



In this tutorial, we will be building a demo web application for a Dog Rescue organization that uses JdbcTemplate and Thymeleaf. For this example, we will be using a MySQL database. However, this example is not limited to MySQL and the database could be swapped out for another type with ease.

You can browse and download the code on Github as you follow this example.

1 – Project Structure

The project uses a typical Maven structure. You may notice I am using Spring Tool Suite, which JT is not a fan of!

Project structure of Spring Boot Thymeleaf JdbcTemplate tutorial


2 – Dependencies

Besides typical Spring Boot Starter dependencies, we include Thymeleaf and MySQL connector.


3 – Configuration

We configure all our datasource information here in the application.properties. Later we will autowire this for our JdbcTemplate use.


4 – Database Initialization

When our application starts, these SQL file will be automatically detected and ran. In our case, we will drop the table “dog” every time the application starts, create a new table named “dog” and then insert the values shown in data.sql.

You may recall that “vaccinated” is a Boolean value in Java. In MySQL Boolean is a synonym for TINYINT(1), so we can use this data type for the column.



5 – Model/Entity

Here we define the characteristics of a dog that we want to know for our Dog Rescue. The getters and setters were auto created and it is suggested to do this to save time.

6 – Repository

We extend the CrudRepository for our DogRepository. The only additional method we create is a derived query for finding a dog by name.

7 – Service

Using the SOLID principles that JT discusses on the site here :SOLID Principles , we build a service interface and then implement that interface.



Here we implement the methods mentioned in DogService.java.

  • addADog – is an example of how to add a record using JdbcTemplate’s update method. It takes three parameters: String, Date and Boolean.
  • deleteADOG – is an example of how to delete a record using JdbcTemplate’s update method. It takes two parameters: Long (id) and String (name).
  • List atriskdogs – is an example of how to select records using JdbcTemplate’s query method. This uses a
    ResultSetExtractor. It takes one parameter: Date. The method returns records of dogs that were rescued before that date that have not been vaccinated (Boolean value of false).
  • long getGeneratedKey – is an example of how to insert records using JdbcTemplate’s query method with PreparedStatementCreator and retrieve a generated key. It takes the same parameters as the other insert example: String, Date and Boolean.

8 – Controller


    • @GetMapping(value = “/”) – there is an optional requirement to provide a search value of type Date in yyyy-MM-dd format. This variable is called q (for “query”) and if it is not null then we will create an ArrayList of all dogs rescued before that date who have not been vaccinated. This ArrayList is called dogModelList and added as an attribute known as “search”. This attribute will be used in our Thymeleaf template.
      Because of its ease of use,
      we use the built in findall method of the CrudRepository to create a list of all dogs in the repository and add it as an attribute, which will also be used by Thymeleaf.
    • @PostMapping(value = “/”) – we request all the parameters that will be passed in our HTML form. We use these values to add a dog to our database.
    • @PostMapping(value = “/delete”) – we request the parameters needed to delete a dog. After the dog is deleted, we redirect the user back to our homepage.
    • @PostMapping(value = “/genkey”) – this is the mapping for inserting a record that returns a generated key. The generated key is printed to standard out in our example.

9 – Thymeleaf template

As this is a basic example application to demonstrate approaches to JdbcTemplate, JPA, Thymeleaf, and other technologies, we have just this one page with a minimalist user interface.

      • Using th:each we are able to iterate through all the records in our dog table
      • Using th:text with the variable and field name, we can display the record. I.E. th:text=”${dogs.id}
      • Using th:if=”${not #lists.isEmpty(search), we prevent the web page from showing the table of search results for dogs at risk (not vaccinated) unless there are results to be shown.
      • With our forms, we map the request to a specific URI and specify names for the inputs of our form that match the parameters in our controller.