It has been a while since I wrote this blog about how I discovered Spring Boot. A surgery to fix my ACL and meniscus tear has kept me away from a lot of things, more about that in a different blog. But it is time we got a little intimate with Spring Boot.
In this blog we will look at how to setup a simple Spring Boot application with JPA/Hibernate. I remember shying away from writing/experimenting any code whenever I heard – setting up something with Spring. Those were the dark ages ! Well, if you haven’t tried the super cool Spring Initializr yet , it is high time you did. You can setup Spring based projects in an absolute flash !
All I did was enter JPA, H2 in the Search for dependencies box and imported the project in my IDE.
Dependencies
The pom.xml from the imported project contains the following important dependencies:
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<dependencies> | |
<dependency> | |
<groupId>org.springframework.boot</groupId> | |
<artifactId>spring-boot-starter-data-jpa</artifactId> | |
</dependency> | |
<dependency> | |
<groupId>com.h2database</groupId> | |
<artifactId>h2</artifactId> | |
<scope>runtime</scope> | |
</dependency> | |
<dependency> | |
<groupId>org.springframework.boot</groupId> | |
<artifactId>spring-boot-starter-test</artifactId> | |
<scope>test</scope> | |
</dependency> | |
</dependencies> |
We added 2 things in the search box, JPA and H2 and so now the pom.xml contains dependencies corresponding to that:
- The spring-boot-started-data-jpa dependency brings in the latest version of the Hibernate, support for transactions, spring-data-jpa etc. Not only does it bring in the latest versions but also compatible versions. Notice that we need not add spring-orm and all the pain to setup the latest and compatible versions of Hibernate, JPA, transactions. This is done automatically for us.
- The h2 dependency above is for an embedded database that we will be using. One can easily replace that with the respective database in your project. Since h2 database will be present on the classpath, Spring Boot will configure the h2 database for us. If you add the dependency for Mysql database, Spring Boot will help configuring a MySql database.
JPA Entity
To keep things simple, we are going to create a Project entity which contains id, name and description and persist this data. We will use Spring Data to persist and fetch the data.
Application starting point
The starting point in our application is the SpringBootJpaApplication.java:
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package com.boot.jpa; | |
import org.springframework.boot.SpringApplication; | |
import org.springframework.boot.autoconfigure.SpringBootApplication; | |
@SpringBootApplication | |
public class SpringBootJpaApplication { | |
public static void main(String[] args) { | |
SpringApplication.run(SpringBootJpaApplication.class, args); | |
} | |
} |
The output from running the file above: (lines 4 – 8)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
… | |
2017-06-06 00:56:10.523 INFO 616 — [ main] o.s.j.e.a.AnnotationMBeanExporter : Registering beans for JMX exposure on startup | |
2017-06-06 00:56:10.812 INFO 616 — [ main] o.h.h.i.QueryTranslatorFactoryInitiator : HHH000397: Using ASTQueryTranslatorFactory | |
2017-06-06 00:56:11.204 INFO 616 — [ main] com.boot.jpa.ProjectInitRunner : Project[ id = 1 , name = 'Java' , description = 'Java based project for a bank'] | |
2017-06-06 00:56:11.205 INFO 616 — [ main] com.boot.jpa.ProjectInitRunner : Project[ id = 2 , name = 'Scala' , description = 'Scala based project for an oil company'] | |
2017-06-06 00:56:11.206 INFO 616 — [ main] com.boot.jpa.ProjectInitRunner : Project[ id = 3 , name = 'Apache Kafka' , description = 'Kafka based project for a data mining company'] | |
2017-06-06 00:56:11.206 INFO 616 — [ main] com.boot.jpa.ProjectInitRunner : Getting project by name | |
2017-06-06 00:56:11.268 INFO 616 — [ main] com.boot.jpa.ProjectInitRunner : Scala based project id 2 | |
… |
Sample Data added via the Initializer
In addition to the SpringBootJpaApplication.java, there is a ProjectInitRunner.java which is run by Spring Boot on startup. It contains initialization code which inserts some Project entities into the H2 database and then fetches one of the project details. This class is run on start up as it implements the CommandLineRunner interface. I am currently using it to persist some data into the H2 database.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package com.boot.jpa; | |
import java.util.List; | |
import org.slf4j.Logger; | |
import org.slf4j.LoggerFactory; | |
import org.springframework.beans.factory.annotation.Autowired; | |
import org.springframework.boot.CommandLineRunner; | |
import org.springframework.context.annotation.Configuration; | |
@Configuration | |
public class ProjectInitRunner implements CommandLineRunner { | |
private static final Logger logger = LoggerFactory.getLogger(ProjectInitRunner.class); | |
@Autowired | |
private ProjectRepository projectRepository; | |
@Override | |
public void run(String… args) throws Exception { | |
// Save | |
projectRepository.save(new Project("Java", "Java based project for a bank")); | |
projectRepository.save(new Project("Scala", "Scala based project for an oil company")); | |
projectRepository.save(new Project("Apache Kafka", "Kafka based project for a data mining company")); | |
// Find all projects. | |
List<Project> projects = projectRepository.findAll(); | |
projects.forEach(project -> logger.info(project.toString())); | |
// Get a project by name | |
logger.info("Getting project by name"); | |
Project project = projectRepository.findByName("Scala"); | |
logger.info("Scala based project id " + project.getId()); | |
} | |
} |
The Spring Boot starter data jpa brings in the Spring Data project which we are using to persist and retrieve the data.
Package structure
This is how the package structure looks :
Gotchas – Packages and Spring component scanning
Since all the classes were in the same package, the @SpringBootApplication annotation simply scanned and picked up all classes which were in the same package. This works as the @SpringBootApplication does Auto Configuration for us via the @EnableAutoConfiguration annotation. This would also work if other Spring beans were in sub or child packages.
If the Repository and the entities were in a different package with respect to the SpringBootJpaApplication.java which contains the main method, we need to do slightly more work:
As shown above, Project.java and ProjectRepository.java are in a completely different package as compared to the class containing the main method. We need to now inform Spring Boot to enable/scan the repository and entity related classes. This is simply done by modifying the SpringBootJpaApplication.java and adding 2 annotations, @EnableJpaRepositories and @EntityScan. The annotations contain the information about packages that need to be scanned to enable the Jpa repository and scan the JPA entity related classes.No other change is needed and everything runs as usual.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package com.boot.jpa; | |
import org.springframework.boot.SpringApplication; | |
import org.springframework.boot.autoconfigure.SpringBootApplication; | |
import org.springframework.boot.autoconfigure.domain.EntityScan; | |
import org.springframework.data.jpa.repository.config.EnableJpaRepositories; | |
@SpringBootApplication | |
@EnableJpaRepositories(basePackages="com.boot.repository") | |
@EntityScan(basePackages = "com.boot.repository") | |
public class SpringBootJpaApplication { | |
public static void main(String[] args) { | |
SpringApplication.run(SpringBootJpaApplication.class, args); | |
} | |
} |
Conclusion
So it is really quite simple and super quick to setup a Spring Boot JPA project. The starter projects brings in all the required dependencies and also provides us with default and most importantly right and latest configurations if we don’t specify any. We can always override the default configurations by adding our own and Spring Boot will happily skip that part.
I think in case of Spring Boot, we can really say – Less (no?) Pain, More Gain !
All the code can be found here : Github
One thought on “Spring Boot and Hibernate – Quick Introduction”