Spring Boot Web Application – Part 3 – Spring Data JPA

Spring Boot Web Application – Part 3 – Spring Data JPA

74 Comments

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 set up 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 workhorses. 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 an 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. It’s a great database, but it’s not really meant to run from a laptop.

The persistence API in Java follows the Interface Segregation design principle of object-oriented design. So, it’s 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 set up 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.

Spring Framework 5
Click here to learn about my Spring Framework 5: Beginner to Guru online 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 Jenkins 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, set up 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.

<dependency>
    <groupId>com.h2database</groupId>
    <artifactId>h2</artifactId>
</dependency>

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 a JPA implementation. There’s a number of open source and commercial JPA implementations available.

Spring Framework 5
Become a Spring Framework Guru! Click here to learn about my Spring Framework 5: Beginner to Guru online 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 include Hibernate. Spring Boot will automatically configure default Hibernate properties.

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>

Example JPA Entity

In our example application, we’re going to use a product for an e-commerce website. I’ll cover JPA mappings in more detail in future posts. It’s 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

package guru.springframework.domain;

import javax.persistence.*;
import java.math.BigDecimal;

@Entity
public class Product {
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Integer id;

    @Version
    private Integer version;

    private String productId;
    private String description;
    private String imageUrl;
    private BigDecimal price;

    public String getDescription() {
        return description;
    }

    public void setDescription(String description) {
        this.description = description;
    }

    public Integer getVersion() {
        return version;
    }

    public void setVersion(Integer version) {
        this.version = version;
    }

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getProductId() {
        return productId;
    }

    public void setProductId(String productId) {
        this.productId = productId;
    }

    public String getImageUrl() {
        return imageUrl;
    }

    public void setImageUrl(String imageUrl) {
        this.imageUrl = imageUrl;
    }

    public BigDecimal getPrice() {
        return price;
    }

    public void setPrice(BigDecimal price) {
        this.price = price;
    }
}

 

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 an 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

package guru.springframework.repositories;

import guru.springframework.domain.Product;
import org.springframework.data.repository.CrudRepository;

public interface ProductRepository extends CrudRepository<Product, Integer>{
}

 

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

package guru.springframework.configuration;

import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.autoconfigure.domain.EntityScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
import org.springframework.transaction.annotation.EnableTransactionManagement;

@Configuration
@EnableAutoConfiguration
@EntityScan(basePackages = {"guru.springframework.domain"})
@EnableJpaRepositories(basePackages = {"guru.springframework.repositories"})
@EnableTransactionManagement
public class RepositoryConfiguration {
}

 

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, check out 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 a 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

package guru.springframework;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.test.context.web.WebAppConfiguration;


@RunWith(SpringRunner.class)
@SpringBootTest(classes = SpringBootWebApplication.class)
@WebAppConfiguration
public class SpringBootWebApplicationTests {

  @Test
  public void contextLoads() {
  }

}

 

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 the 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

package guru.springframework.bootstrap;

import guru.springframework.domain.Product;
import guru.springframework.repositories.ProductRepository;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationListener;
import org.springframework.context.event.ContextRefreshedEvent;
import org.springframework.stereotype.Component;

import java.math.BigDecimal;

@Component
public class ProductLoader implements ApplicationListener<ContextRefreshedEvent> {

    private ProductRepository productRepository;

    private Logger log = Logger.getLogger(ProductLoader.class);

    @Autowired
    public void setProductRepository(ProductRepository productRepository) {
        this.productRepository = productRepository;
    }

    @Override
    public void onApplicationEvent(ContextRefreshedEvent event) {

        Product shirt = new Product();
        shirt.setDescription("Spring Framework Guru Shirt");
        shirt.setPrice(new BigDecimal("18.95"));
        shirt.setImageUrl("http://springframework.guru/wp-content/uploads/2015/04/spring_framework_guru_shirt-rf412049699c14ba5b68bb1c09182bfa2_8nax2_512.jpg");
        shirt.setProductId("235268845711068308");
        productRepository.save(shirt);

        log.info("Saved Shirt - id: " + shirt.getId());

        Product mug = new Product();
        mug.setDescription("Spring Framework Guru Mug");
        mug.setImageUrl("http://springframework.guru/wp-content/uploads/2015/04/spring_framework_guru_coffee_mug-r11e7694903c348e1a667dfd2f1474d95_x7j54_8byvr_512.jpg");
        mug.setProductId("168639393495335947");
        productRepository.save(mug);

        log.info("Saved Mug - id:" + mug.getId());
    }
}

 

Running Product Loader

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

SpringBootWebApplication.java

package guru.springframework;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class SpringBootWebApplication {

    public static void main(String[] args) {
        SpringApplication.run(SpringBootWebApplication.class, args);
    }
}

 

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.

 2015-06-25 09:41:54.207  INFO 29073 --- [           main] o.s.j.e.a.AnnotationMBeanExporter        : Registering beans for JMX exposure on startup
2015-06-25 09:41:54.283  INFO 29073 --- [           main] g.s.bootstrap.ProductLoader              : Saved Shirt - id: 1
2015-06-25 09:41:54.285  INFO 29073 --- [           main] g.s.bootstrap.ProductLoader              : Saved Mug - id:2
2015-06-25 09:41:54.370  INFO 29073 --- [           main] s.b.c.e.t.TomcatEmbeddedServletContainer : Tomcat started on port(s): 8080 (http)

To run the Spring Boot application from IntelliJ, simply right click on the SpringBootWebApplicationand 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 set up 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.

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 the 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

About jt

    You May Also Like

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

    1. July 24, 2015 at 6:53 am

      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

      Reply
      • July 25, 2015 at 7:28 am

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

        Thanks!!

        Reply
    2. July 31, 2015 at 1:28 am

      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?

      Reply
      • July 31, 2015 at 7:27 am

        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

        Reply
    3. August 9, 2015 at 7:13 pm

      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?

      Reply
      • February 5, 2016 at 10:29 am

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

        Reply
    4. August 18, 2015 at 8:02 am

      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”

      Reply
      • August 18, 2015 at 8:20 am

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

        Reply
        • August 18, 2015 at 8:31 am

          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.

          Reply
    5. August 18, 2015 at 8:49 am

      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.

      Reply
    6. August 19, 2015 at 8:54 am

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

      Reply
      • August 19, 2015 at 9:06 am

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

        I need more hours in the day! LOL

        Reply
        • August 27, 2015 at 10:54 pm

          Awesome, can’t wait 🙂

          Reply
    7. September 8, 2015 at 5:50 am

      Saved my day – thanks

      Reply
    8. September 21, 2015 at 7:57 am

      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)

      Reply
      • November 12, 2015 at 3:22 am

        Thanks man! saved me. 😀

        Reply
      • January 9, 2016 at 4:54 am

        Saved me too. Thank you

        Reply
      • March 10, 2016 at 10:57 am

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

        Reply
      • November 18, 2017 at 9:48 am

        DevLouis where i can change the JDBC URL???

        Reply
    9. October 24, 2015 at 3:03 pm

      Thanks man for this awesome tutorials !

      Reply
    10. November 12, 2015 at 3:06 am

      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!

      Reply
      • November 13, 2015 at 11:11 am

        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.

        Reply
    11. November 28, 2015 at 1:15 pm

      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!

      Reply
    12. November 30, 2015 at 3:41 pm

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

      Reply
    13. December 29, 2015 at 11:25 pm

      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

      Reply
    14. January 3, 2016 at 1:35 am

      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?

      Reply
      • January 3, 2016 at 12:27 pm

        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.

        Reply
        • January 4, 2016 at 9:28 am

          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?

          Reply
          • January 4, 2016 at 10:02 am

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

            Reply
            • January 4, 2016 at 10:28 am

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

            • January 4, 2016 at 12:58 pm

              No, I don’t have any examples handy.

    15. January 11, 2016 at 6:37 am

      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?

      Reply
    16. January 12, 2016 at 6:16 pm

      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 !

      Reply
      • January 12, 2016 at 6:20 pm

        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.

        Reply
        • January 12, 2016 at 6:49 pm

          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!!!

          Reply
          • January 12, 2016 at 7:18 pm

            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.

            Reply
        • January 12, 2016 at 7:21 pm

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

          Reply
    17. March 9, 2016 at 11:39 am

      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

      Reply
      • March 9, 2016 at 11:50 am

        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.

        Reply
    18. March 10, 2016 at 12:27 pm

      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.

      Reply
    19. May 1, 2016 at 8:58 pm

      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.

      Reply
      • May 2, 2016 at 11:16 am

        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.

        Reply
        • November 16, 2016 at 10:17 am

          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.

          Reply
          • November 16, 2016 at 1:37 pm

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

            Reply
            • November 17, 2016 at 12:12 am

              Hi,
              Thanks for your reply.

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

              Any pointers?
              -Akhila

            • November 17, 2016 at 12:32 am

              Hi,
              Thanks for your reply.

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

              Any pointers?

              -Akhila

            • November 17, 2016 at 5:25 am

              Hi,

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

              ~ Akhila

          • June 21, 2017 at 10:02 am

            Hello Akhila,

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

            Reply
            • January 14, 2019 at 3:38 pm

              I’ve run into the same issue using postgres, there is someone to help? Thanks in advance.

    20. May 20, 2016 at 8:34 am

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

      Reply
    21. June 1, 2016 at 4:48 pm

      excellent post, waiting for more!

      Reply
      • June 2, 2016 at 10:35 am

        Thanks!!

        Reply
    22. June 11, 2016 at 1:20 am

      Great tutorial. I’ll join the courses soon!

      Reply
    23. June 15, 2016 at 5:20 pm

      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

      Reply
      • June 15, 2016 at 5:27 pm

        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.

        Reply
        • June 15, 2016 at 6:03 pm

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

          Reply
    24. August 20, 2016 at 2:28 pm

      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!

      Reply
      • August 20, 2016 at 3:45 pm

        Glad it helped!

        Reply
    25. April 10, 2017 at 2:33 pm

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

      Reply
    26. July 18, 2017 at 2:31 pm

      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.

      Reply
      • July 18, 2017 at 2:39 pm

        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.)

        Reply
    27. July 28, 2017 at 12:32 pm

      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.

      Reply
    28. January 6, 2018 at 10:22 pm

      ProductLoader logging update:

      import org.apache.logging.log4j.LogManager;
      import org.apache.logging.log4j.Logger;

      static final Logger LOGGER = LogManager.getLogger(ProductLoader.class);

      LOGGER.info(“Saved Shirt – id: ” + shirt.getId());

      Reply
    29. August 23, 2018 at 2:34 pm

      When I add the ProductLoader class and launch, I get this error:

      Parameter 0 of method setProductRepository in com.example.demo.bootstrap.ProductLoader required a bean of type ‘com.example.demo.repositories.ProductRepository’ that could not be found.

      Action:

      Consider defining a bean of type ‘com.example.demo.repositories.ProductRepository’ in your configuration.

      I’ve tried a manual ‘ComponentScan’ but have been unable to resolve this issue.

      Any tips?

      Joe

      Reply
      • August 23, 2018 at 2:36 pm

        If you’re getting this error, either the class is not annotated properly, or the package is not getting scanned.

        Reply
    30. October 22, 2020 at 2:58 am

      There was a error for me al follows:
      Driver org.h2.Driver is not suitable for jdbc:h2:mem:testdb 08001/0

      Reply

    Leave a Reply

    Your email address will not be published. Required fields are marked *

    This site uses Akismet to reduce spam. Learn how your comment data is processed.