, ,

Spring Boot Web Application – Part 3 – Spring Data JPA

In the first part of this tutorial series on creating a web application using Spring Boot, I showed how to use Spring Initializr to create the Maven project we’re using in this example. In the second part of the tutorial series, I showed you how to configure Spring MVC and ThymeLeaf templates to display a basic web page via Tomcat. In this part of my Spring Boot tutorial series, we’ll setup the H2 database and Spring Data JPA. We will use these tools to persist data to the database in our Spring Boot Web Application.

Database Persistence with Spring Boot

Spring Boot comes with pre-configured options for relational databases. Like other things in Spring Boot, these are enabled by simply having the dependency on your classpath.

While all the interest in the media is around No-SQL databases, relational databases are time proven work horses. They are not going anywhere soon. If you’re doing enterprise application development with the Spring Framework, you’re probably going to be using a relational database.

Hibernate / JPA does a great job of abstracting the persistence layer. If you want to change from Oracle to DB2 or to MySQL, it is just a matter of changing the database drivers. The JPA mapping code you use on your domain POJOs doesn’t change. Your application code does not change.

NOTE – the above statement is 95% true. When changing databases with complex mappings, you’re going to hit minor edge cases here and there.

When developing Spring applications, it is very common to use a in memory database for your development, and then a real database installation for your testing and production environments. Oracle is a great database, but it’s also BIG and resource intensive. I’ve run Oracle on a laptop. It takes a lot of resources. Its a great database, but its not really meant to run from a laptop.

The persistence API in Java follows the Interface Segregation design principle of object oriented design. So, its easy to plug in a different persistence implementation. With Spring managing the dependency injection for us, it makes swapping databases in and out very easy.

What we are going to do in this tutorial is setup an in-memory database, configure a JPA entity, setup Hibernate to automatically create the database tables, and on startup add data to the database for our use and testing.

By doing this, each time we start our application, we have a newly created database, with known data populated into the database tables. It sounds like a lot of work, but it’s really not much. And it does not add very much to your startup time. With the speed of modern computers, even a complex set of tables and data is going to load in just a few seconds.

The advantage of doing this for you as the developer is you’re working against known data while you are doing your development. It also sets you up for being able to automate integration and functional tests with a continuous build server such as Jenkins.

Free Spring Tutorial
Click Here for my free Spring Course!

H2 Database

The H2 database is a popular database to use when developing Spring applications. H2 is written in Java and is easily runs as an embedded in-memory database. Because it is an embedded in memory database, it makes your build portable. Your build will run anywhere Maven will run.

If you used a database like Oracle or MySQL, now you’ve introduced an external dependency. Your build is no longer portable. If you wanted to do the build under Jekins on a build server, you’d need to install the database on that server or provide a configuration pointing to a database elsewhere.

By using the H2 database as an embedded in memory database, your build remains portable.

H2 Database and Spring Boot

Configuring the H2 database with Spring Boot is very easy. You just need to add the H2 dependency to your Maven Pom. Spring Boot will automatically create the database, setup all the database JDBC objects, and by default configure Hibernate in a create-drop mode. Thus, when Hibernate starts up, it will scan the JPA annotated classes and automatically generate and execute the SQL code needed to create the database tables.

pom.xml

By adding this dependency to your Maven POM, Spring Boot will automatically configure the H2 database.

H2 Database Console

H2 comes with a really cool web based database console you can use to query the database. This is very handy to use when developing with the H2 database and the Spring Framework. When developing the code for this post, I ran into a couple of “gotchas” with setting up the H2 Database Console with Spring Security. It inspired me to write a blog post about it. If you’re following this tutorial step by step, please complete the steps in this post now.

NOTE: When connecting, be sure your JDBC url is set to ‘jdbc:h2:mem:testdb’.

h2 database console

JPA Entities

JPA, which stands for Java Persistence API, is a Java standard. It’s important to remember JPA is just the API (Application Programming Interface) standard. Java itself does not ship with JPA included. For that, you need to include an JPA implementation. There’s number of open source and commercial JPA implementations available.

Free Spring Tutorial
Click here for my free Spring course!

Hibernate and Spring Boot

Hibernate is by far the most popular. When you include the Spring Data JPA dependency in your Maven POM, Hibernate is included by default. As typical with Spring Boot, Hibernate is setup and configured with sensible default properties.

pom.xml

The Spring Data JPA dependencies includes Hibernate. Spring Boot will automatically configure default Hibernate properties.

Example JPA Entity

In our example application, we’re going to use a product for a ecommerce website. I’ll cover JPA mappings in more detail in future posts. Its a subject that could easily be a tutorial series of its own. For now, we just need a product entity.

By convention, I like to put my entity classes in a package called ‘domain’. This is just my personal habit. Probably something I picked up from working so much with the Grails framework.

Product.java

Spring Data JPA

Using Spring Data JPA can save you a lot of time when interacting with the database. Spring Data JPA implements the Repository Pattern. This design pattern was originally defined by Eric Evans and Martin Fowler, in their book Domain Driven Design. This is one of those time test computer science books, over a decade old, still remains relevant today.

You don’t need to use Spring Data JPA for this type of project. But using Spring Data JPA will make your life as a developer easier. A common alternative to Spring Data JPA would be to use the widely accepted DAO pattern, The DAO pattern is very similar to the Repository Pattern. The advantage of using Spring Data JPA is that you’ll be writing a lot less code. Spring Data JPA works a lot like Spring Integration Gateways, where you define an interface, and Spring provides the implementation at run time.

Spring Data JPA CRUD Repository

The Spring Data JPA CRUD Repository is my favorite feature of Spring Data JPA. Similar to coding with a Spring Integration Gateway, you can just define an interface. Spring Data JPA uses generics and reflection to generate the concrete implementation of the interface we define.

Defining a repository for our Product domain class is as simple as defining a interface and extending the CrudRepository interface. You need to declare two classes in the generics for this interface. They are used for the domain class the repository is supporting, and the type of the id declared of the domain class.

For our Product domain class we can define a Spring Data JPA repository as follows.

ProductRepository.java

Integration Testing with Spring Data JPA and JUnit

Even though we are building a web application, we can test the persistence layer without creating a WAR file, and without deploying to Tomcat. We want to set up some integration tests to test our JPA mapping and interactions with the Spring Data JPA repository. To do this, we’re going to take advantage of the auto-configuration options available to us in Spring Boot. By doing this, there is a lot of boilerplate code we don’t need to write.

Spring Data JPA Repository Test Configuration

For our integration tests, we’re going to use a Spring Context to wire up beans to support our tests. If we were not using Spring Boot, we’d need to create a number of beans ourselves. Normally we would need to create:

  • The H2 data source
  • The Hibernate Entity Manager
  • A JPA Transaction Manager

But since we’re using Spring Boot, we don’t need to write code to create these beans. For the purposes of our integration tests for our Spring Data JPA repositories, we can complete our Java configuration with just annotations.

RepositoryConfiguration.java

While this is an empty Java class file, each of the annotations is very important.

  • @Configuration  tells the Spring Framework this is a Java configuration class.
  • @EnableAutoConfiguration tells Spring Boot to do its auto configuration magic. This is what has Spring Boot automatically create the Spring Beans with sensible defaults for our tests.
  • @EntityScan specifies the packages to look for JPA Entities.
  • @EnableJpaRepositories enables the auto configuration of Spring Data JPA.
  • @EnableTransactionManagement Enables Spring’s annotation driven transaction management

Through this configuration, we have everything we need to use the H2 database with Spring Data JPA in JUnit tests.

Spring Data JPA JUnit Integration Test

With our Spring Java configuration done, our JUnit integration test becomes very simple to write. If you’re new to writing JUnit Integration tests with the Spring Framework, checkout this post where I go into this subject much deeper than I am here. Or if you’re new to JUnit, you may wish to start here.

In this post, I am not going to go in depth with Spring Data JPA. This is fairly large and complex project in the Spring Framework. We’re going to use the CRUD repository from Spring Data JPA. CRUD stands for Create, Read, Update, Delete. Your basic persistence operations. Simply extending the Spring Data JPA’s CRUD Repository interface, as we did above, for the specified Entity we will get methods which will:

  • Save an entity
  • Find an entity based on its ID
  • Check if an entity exists based on its ID
  • Get a list of all entities
  • Get a count of all entities
  • Delete an entity
  • Delete all entities

I’ve written a simple integration test for the Spring Data JPA repository I defined above. In the test, I’m going to do some basic operations, like creating an entity, saving an entity, and fetching an entity from the database. While I’ve written a minimal amount of code in this example, the data is really getting saved into a database. You don’t see any SQL happening, but it is getting generated by Hibernate for us. We’re using an in memory H2 database, which goes away once the test is done. But we could easily change the test to save to a database on disk and prove we’ve persisted the test data. Once you grasp how little code you are writing, and how much is happening under the covers for you, you can appreciate what a powerful tool Spring Data JPA is.

ProductRepositoryTest.java

Loading Data Using Spring Data on Startup

Hibernate has a feature to load data on startup. Simply place a file called import.sql on your classpath, and Hibernate will execute the SQL statements in file.

Cool, right?

No, not really. It has us writing SQL statements. What if you’re just doing a prototype? If you change your Entity class, you need to update the SQL. When you’re using Spring Data JPA, this not a very elegant solution. I’m going to shamelessly steal from the Grails community, which has a bootstrap.groovy file which allows us to do things on startup. We have a mature ORM in Hibernate and a really cool tool called Spring Data JPA – why wouldn’t we want to use these tools to load data on startup?

Creating a Product Loader

I previously wrote a post on running code in Spring Boot on Startup. We can use this technique here to utilize the Spring Data JPA repository to populate some data for us to use on startup.

ProductLoader.java

This class implements the ApplicationListner interface, so it gets called upon the ContextRefresedEvent on startup. We’re using Spring to inject the Spring Data JPA repository into the class for our use. In this example, I’m creating two entities and saving them to the database.

ProductLoader.java

Running Product Loader

We still have our Spring Boot application class which was created by the Spring Initializr for us.

SpringBootWebApplication.java

When we run this class, it will startup tomcat for us. In the console log, we can see the output of the log statements from our ProductLoader  class.

To run the Spring Boot application from IntelliJ, simply right click on the SpringBootWebApplication class and select “Run ‘SpringBootWebApplica…'”

run spring boot application from intellij

H2 Database Console

While we still have Tomcat up, We can use the H2 Database Console to browse the H2 database console at the URL http://localhost:8080/console.

Note: If you have not, you will need to setup the H2 database console as explained here.

From the H2 database console, you can see the PRODUCT table has been created by Hibernate, and two records have been inserted via the Spring Data JPA repository we created in this tutorial.

h2 database console showing data saved by Spring Data JPA

Conclusion

In this part of my tutorial series on creating a web application using Spring Boot, I’ve shown you how to setup the H2 database and Spring Data JPA for use. You can see how easy it is to persist data to the database using Spring Data JPA repositories.

In the next part of this tutorial series, I’ll show you how to use data retrieved from the Spring Data JPA repository and display it on a web page using Spring MVC, and how to create and update records.
&nbsp:

Free Introduction to Spring Tutorial

Are you new to the Spring Framework? Checkout my FREE Introduction to Spring Course!.

Get The Code

I’ve committed the source code for this post to github. It is a Maven project which you can download and build. If you wish to learn more about the Spring Framework, I have a free introduction to Spring tutorial. You can sign up for this tutorial in the section below.

The source code for this post is available on github. You can download it here.

Save

Share

You May Also Like

65 comments on “Spring Boot Web Application – Part 3 – Spring Data JPA

  1. Hi
    Very good and understandable tutorial 🙂
    Is there a 4th tutorial also available?
    I’ve noticed that github contains part4 and part5 source code, but I don’t want to simply copy/paste code,
    because you explain so well how something has been done and how everything works.

    Keep up this good blog:)

    Regards

    • Yes, I do have a couple more parts in the series to publish. I should have them done in the next few weeks.

      Thanks!!

  2. Hi Jt, I am using Spring-data-jpa, do you know if Spring-data-jpa is thread safe by default? or Do I need to configure any property/annotation in my spring project?

    • I expect that it is by default. But the longer answer is it probably depends on your use case.

      I suggest posting your question on Stack Overflow and see if one of Pivotal guys responds. see: http://spring.io/questions

  3. Nice tutorial so far. I like using the ProductLoader to create test data. However, this is currently running in the production side and not the test environment. Will you show changing that to be loaded only in tests?

    • I’ve run into the same issue. Components on the test side are not getting loaded. Any hints?

  4. Hi! Nice post.
    Do you know if there is some way to map my query result(using jpa) to a POJO? Because I have a native query and I want to map this result to a simple Pojo, not the entity (sorry for my bad english).

    Ex:

    I have this repository interface:

    @Repository
    public interface UserRepository extends JpaRepository, JpaSpecificationExecutor

    And I want to map one native query to UserMod:

    @Query(nativeQuery = true, value = USER_PROFILE)
    UserMod loadProfile(@Param(“idUser”) Long idUser);

    What happening is that Spring says:

    “ConverterNotFoundException: No converter found capable of converting from type java.math.BigInteger to type labex.controller.mod.UserMod”

    • No, I don’t. I’d just use a CRUD repository, then map the JPA entity to your target POJO.

      • Well, thank you for your time. I found that I can map the resultset to Object[ ], but I have to map it anyway. Maybe using reflection I can automate things.

  5. If your property names match, it would be a piece of cake in Groovy.

    Reflection is cool, but slow too. Not something you want to do if you need it to be performant.

  6. I like it ! Thanks John for this nice Spring tutorials series well coupled with design patterns.
    I’m eager to see next one 😉

    • Thanks! The next post is 70% done. Should be up in the next few days.

      I need more hours in the day! LOL

      • Awesome, can’t wait 🙂

  7. Saved my day – thanks

  8. Hey. i’m a young developer and i just started my mission in a new company.
    thanks a lot for your guide. Project involving Maven / Spring boot / Hibernate are quite messy a the first look. you helped me getting through this. 😀

    To the new reader : Be really careful to access the correct h2 database and to change the JDBC URL by : jdbc:h2:mem:testdb

    I had spent some hours before finding out what was going on x)

    • Thanks man! saved me. 😀

    • Saved me too. Thank you

    • yes me too – make sure you use jdbc:h2:mem:testdb

  9. Thanks man for this awesome tutorials !

  10. Hi Spring Guru jt,

    First of all, I would like to thank you for setting this tutorial up. As a newbie to Spring (I’m from Grails) I find it hard to find somewhere to start and find enlightenment, but then I saw your blog! Awesome and fantastic articles. May the force be with you spring guru! 😀

    I just want to point out some typos in the article, “This class implements the ApplicationListner interface, so it is called with the ContextRefresedEvent”.

    Waiting for the next article, thanks!

    • Thank you!!

      I love Grails. With Grails, if you don’t know Spring inside and out, you’re fighting with one arm behind your back!

      Follow my Facebook page or my Google Plus page for all my latest updates.

      Thanks for pointing out the typo, I updated the post for clarity.

  11. Hey JT

    Great series! A minor correction – The R in CRUD stands for Read, not CReate.

    Thanks for making sense of a lot of the Spring architecture to those of us new to Spring Boot!

  12. Thanks Mark – I knew that… Brainfart on my part. Thanks for pointing it out.

  13. hello , by extending SimpleJPARepository i have implemented and wrote update method. but with spring boot 1.3.1 version. it is giving connect read only exception . could you please let me know how to update ManyToMany relation entities with spring boot jpa repositories with 1.3.1 boot version

  14. Hi,
    Your sample is very clear ad simple for CRUD! They can find all or find by id, but I want to find by a normal column not id,how can I do?

    • You can use a query in Spring Data JPA by specifying a method findBy in the interface. Spring Data JPA will build the query for you. Very VERY cool feature of Spring Data JPA.

      • Thanks for your suggestion, I got it!
        Then I have another question about using Dynamic Multiple Databases, I want to use different MySQLs on different servers base on login company, update or read, so I hope that I can set connection before I do any DB process, is this possible with Spring Data JPA?

        • Yes, that is possible. I did multiple datasources for a client a few years ago.

          • Can you show me examples source code? Or where can I find such samples?

          • No, I don’t have any examples handy.

  15. Can you tell me how remove persistence.xml in a Spring project? I found your project doesn’t use that file! how can I do it?

  16. Hi, i actually use spring boot with jpa ,rest micro services and angularjs, i need to save a document in mysql database, please, how can i do it??? I searched a lot in the net, but it seems no topic for this question.
    Please can you help me !

    • I’ve never been a big fan of storing documents in the database. Usually better to store a file location (string) than a binary object. It can be done, but not always the best option.

      • Can we store file location so ? i am open to any kind of solutions, because i am working on like an international journal project, so i need a way to store my papers!!!

        • If it was me, I’d do something like store the file in Amazon S3 (File gets backed up on multiple servers, in multiple data centers by S3), then store the URL of the file in the DB. The URL is just a string property.

      • Thank you for your opinion (Y), it’s a nice idea^^

  17. Hello, I’m starting a new web project and would like to know if you have some guidance on how to separate the application into individual Data, Business, and Presentation/UI maven project.

    It’s a Spring MVC dashboard web app for metrics but I envision both data and services layers being reused in another completely different Spring MVC application specifically as a more Management/Search engine app. So I would like the data and service projects to have separate configurations and be configured as maven dependencies for the front end. I figure if it’s done this way I can also have separate front end(s) for REST Service(s).

    So what I’m trying to figure out an get ideas is how to properly separate the projects and have the end Presetaion/UI project build the WAR with dependencies to the Service and Data projects.

    The last prototypes for the dashboard and other Business Specific WEb applications I built used a monolithic approach were all the JPA/Services/Controllers were in one project and not reusable. All of Spring configuration was done in the one project.

    Do you have any experience doing this? If not maybe you can recommend someone else or some place I could start doing some research.

    Sorry for this unusual request but I have not found a good point of reference on guidance architecting something like this.

    I appreciate your help.

    And of course, thank you for all your posts and articles. You are an invaluable resource of mine and I give you a ton of credit.

    thank you,

    mbeddedsoft

    • Thanks!

      Yes – I do that all the time. Use a multi-module Maven project to separate the components. The front end modules will be dependent on the back end modules.

  18. Thanks, JT! Your article is very enlightening, helps me to adjust the data in my project.I had some difficulties at first, but were with the spring Eclipse plugin, which was disabled to detect beans.

  19. Hey JT,

    Thanks for these awesome tutorials on Spring Boot! You would think there would be a plethora of good sources online to learn about Spring Boot, but none have come close to the clarity you have in your blog posts. I do, however, have a question regarding the H2 database.

    Say I deploy this project on a live web server. The data that users would enter in would be deleted if I restarted my web server, correct? Is there a way to persist this data, or at the very least back it up? You said in this post that you could “easily change the test to save to a database on disk and prove we’ve persisted the test data”. How would I go about doing this?

    Thanks again for all your help with introducing developers to Spring Boot. Your site really has helped me learn a ton about this facet of Java web development.

    • You’re welcome. If you’re using H2 in memory, yes, the data is lost when the server is bounced. You can write to the file system with H2 like a traditional database, or setup something like MySQL to persist data.

      • Hi,
        I am using postgres to save the data. How do i stop the data from getting lost when the app is closed?
        Thanks in advance.

        • Data should not get lost when the app is closed while using Postgres.

          • Hi,
            Thanks for your reply.

            Unfortunately, in my case, the table “Product” is getting deleted when the app is closed.

            Any pointers?
            -Akhila

          • Hi,
            Thanks for your reply.

            Unfortunately, in my case, the table “Product” is getting deleted when the app is closed.

            Any pointers?

            -Akhila

          • Hi,

            Thanks for your reply.
            Unfortunately, in my case, the table “Product” gets deleted once the app is closed. Any pointers?

            ~ Akhila

        • Hello Akhila,

          i’m also trying to modify launch this application with postgresql not H2,but i have some errors. Can you help me ?

  20. Why is the version set as 0. Isn’t it getting updated on create or edit?

  21. excellent post, waiting for more!

    • Thanks!!

  22. Great tutorial. I’ll join the courses soon!

  23. This is a great project to learn Spring Boot and JPA. But when I ran a maven build after checking out the master I am getting the following compile error.
    ———————
    [ERROR] Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.1:compile (default-compile) on project spring-boot-web: Compilation failure: Compilation failure:
    [ERROR] /C:/Users/460983/git/springbootwebapp/src/main/java/guru/springframework/configuration/WebConfiguration.java:[3,25] package org.h2.server.web does not exist
    [ERROR] /C:/Users/460983/git/springbootwebapp/src/main/java/guru/springframework/configuration/WebConfiguration.java:[12,85] cannot find symbol
    [ERROR] symbol: class WebServlet
    [ERROR] location: class guru.springframework.configuration.WebConfiguration
    ———————

    It is resolved when I explicitly add dependency for H2 in my pom.xml. Is this expected?
    ———–

    com.h2database
    h2
    1.0.60

    • Actually the problem goes away if I just remove the scope tag (runtime) from the h2 dependency. I am not sure if I am missing some configuration.

      • Odd – It was working okay for me. I see you’re on Windows. Might be a difference in platforms. I develop on OSX.

  24. Dude, you just saved my life. I was convinced there had to be a better way to load data into my jpa store apart from raw sql, and couldn’t find anything on the web until I got here. Thanks a billion!

    • Glad it helped!

  25. The code shown under ProductRepositoryTest.java above is for the wrong class (SpringBootWebApplicationTests.java). Great series of articles BTW.

  26. Hello,

    Nice work, but i can undestand why are you using setter method for the ProductRepository in ProductLoader class? Why don’t do in such way

    @Autowired
    private ProductRepository productRepository;

    Thx.

    • Don’t you believe in unit testing your code?

      Autowiring private fields is evil. Always use a setter or constructor. (OO purists recommend using constructors.)

  27. is there way to execute – combination of inserts/updates/deletes in a single batch using spring data JdbcRepository? does it process in a batch if method is annotated with @Transactional.

Leave a Reply