Using Spock to test JPA entities in a Spring Boot application

In my previous post we saw how to test JPA entities along with the Spring Data repository layer in a Spring Boot based application. We made use of JUnit and the AssertJ library.

In this post we will look at how to use the Spock framework to test the same. In fact, in this example, I will be using a combination of Spock based tests along with JUnit tests.To know more about the Spock framework, view the official site here. Spock is a testing and specification framework for Java and Groovy applications.

Let’s get started…

Setup using maven: ( pom.xml)  


<properties>
<spock.version>1.1-groovy-2.4</spock.version>
</properties>
<dependencies>
<dependency>
<groupId>org.spockframework</groupId>
<artifactId>spock-spring</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<compilerId>groovy-eclipse-compiler</compilerId>
<source>1.8</source>
<target>1.8</target>
</configuration>
<dependencies>
<dependency>
<groupId>org.codehaus.groovy</groupId>
<artifactId>groovy-eclipse-compiler</artifactId>
<version>2.9.2-01</version>
</dependency>
<dependency>
<groupId>org.codehaus.groovy</groupId>
<artifactId>groovy-eclipse-batch</artifactId>
<version>2.4.3-01</version>
</dependency>
</dependencies>
</plugin>
</plugins>

  1. We need to add the spock-spring dependency. This will bring in the dependencies required to run Spock based tests in a Spring boot based application.
  2. Notice the use of <spock.version>1.1-groovy-2.4</spock.version>. We are overriding the spock version. Spring Boot 1.5.4 brings in version 1.0 of Spock, however this needs a @ContextConfiguration to run Spock based tests in a Spring Boot application. Overriding the version to 1.1 removes the need to add this annotation.
  3. In the plugin section , we need to add the dependency for groovy-eclipse-compiler which will compile the groovy code. Spock is based on groovy and hence using Spock to write tests means we write groovy code.

Test classes using Spock

As mentioned in my earlier post, let us consider the same example of 2 JPA entities, SocialMediaSite and Users ( OneToMany). A User has an email which we represented as EmailAddress value object.  The test class for this looks as follows:

EmailAddressTest.groovy


package com.boot.test.db;
import com.boot.entity.EmailAddress;
import spock.lang.Specification
public class EmailAddressTest extends Specification {
private static final String testEmail = "test@test.com";
def "throw exception for invalid format of email address"(String emailAddress)
{
when:
"create invalid email address"
def email = new EmailAddress(emailAddress);
then:
"throw exception for invalid format of email address"
def e = thrown(IllegalArgumentException)
e.message == "Email Address is Invalid !"
where:
emailAddress | _
"test@.com" | _
" " | _
null | _
}
def "return valid email address"()
{
when:
"create new email address"
def email = new EmailAddress(testEmail);
then:
"return valid email"
email.toString() == testEmail;
}
}

  1. The test class extends spock.lang.Specification. This is how you begin writing a Spock based test.
  2. Notice the method names are strings, nice descriptive methods names.
  3. The when/then syntax is for assertions. It’s like saying, “Hey, when this happens then check these things”.
  4. The where section is the first test method above is data driven.Notice the first 2 columns, emailAddress and a blank. This is because data driven tables in Spock need 2 columns. We need just one. The next rows supply data to the same method.Hence this method is run with all the values mentioned in the first column starting from the 2nd row. Now that is awesome compared to writing multiple methods which do the same thing or if you are using TestNG, this is done using a DataProvider.
  5. Notice that we have not used any Assertion library here. In Spock this is done using ==.

SocialMediaSiteRepositoryTest.groovy


package com.boot.test.db;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest;
import com.boot.entity.EmailAddress;
import com.boot.entity.SocialMediaSite;
import com.boot.entity.User;
import com.boot.repository.SocialMediaSiteRepository;
import spock.lang.Specification
@DataJpaTest
public class SocialMediaSiteRepositoryTest extends Specification{
@Autowired
private SocialMediaSiteRepository socialMediaSiteRepository;
def facebook = new SocialMediaSite("Facebook", "Online Social Media and Networking Service")
def "find social media site FaceBook by Id" () {
def savedFaceBookEntity = socialMediaSiteRepository.save(facebook)
when: "load facebook entity"
def faceBookEntityFromDb = socialMediaSiteRepository.findOne(savedFaceBookEntity.getId())
then:"saved and retrieved entity by id must be equal"
savedFaceBookEntity.getId() == faceBookEntityFromDb.getId()
}
def "find social media site facebook by name"() {
def savedFaceBookEntity = socialMediaSiteRepository.save(facebook)
when: "find by name FaceBook"
def socialMediaEntity = socialMediaSiteRepository.findByName("Facebook")
then: "saved and retrieved entity by name must be equal"
socialMediaEntity == savedFaceBookEntity
}
def "add users to social mediate site users " () {
setup:
def firstUser = new User("Mar", "Zuckerber", new EmailAddress("mark@mark.com"));
facebook.addUser(firstUser);
def savedFaceBookEntityWithUsers = socialMediaSiteRepository.save(facebook)
when:
def faceBookEntityFromDB = socialMediaSiteRepository.findOne(savedFaceBookEntityWithUsers.getId())
then:
faceBookEntityFromDB.getUsers() != null
faceBookEntityFromDB.getUsers().size() == 1;
}
}

Notice the @DataJpaTest annotation on the class. It  spawns an in-memory data base and runs our tests  against it. Along with this, the JPA entities are scanned, Transactions, Hibernate  and Spring Data are also configured. There is no need to add @ContextConfiguration as we are using Spock 1.1.

Running Spock tests and JUnit tests together

I have added the 2 groovy test files in src/test/groovy.  We can have tests written in JUnit too. I have a JUnit based test class in src/test/java. The groovy eclipse compiler dependency we added in the pom.xml compiles and run tests from both the packages.

Conclusion

This is my first experience with Spock framework and I have thoroughly enjoyed writing tests with it ! There is of course a lot more to the Spock framework. I hope you have enjoyed this quick introduction to Spock for testing Spring Data Repository and JPA entities in a Spring Boot application. The synergy between Spock and the testing changes made in Spring Boot since version 1.4 (test slices) is great !

You can find the project on github.

Testing JPA entities in a Spring Boot application

In this blog we will look at how to get started with testing JPA entities and Spring Data Repository in a Spring Boot based application. We will be using JUnit for the same.

I have observed that a good number of projects do not write any tests for JPA entities or the repository layers which make use of the entities to perform CRUD operations. Writing tests for JPA entities and Spring data repositories can be really effective in checking if all the entities are mapped correctly and ensuring that the repository methods implemented by Spring Data along with the custom methods that you write are behaving in the right way. After all , most applications always talk to a database and if your data is not being handled properly, what is the point of having a great user interface or a well designed business layer ?

Since Spring Boot 1.4, testing these layers has become quite easy and more focused. Let us consider a simple One-Many relation between 2 entities, SocialMediaSite and  a User.

A SocialMediaSite can have many users which is mapped using the @OneToMany JPA annotation.

SocialMediaSite.java 


@Entity
public class SocialMediaSite {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
private String name;
private String description;
@OneToMany(mappedBy = "socialMediaSite", cascade = CascadeType.ALL, orphanRemoval = true)
private List<User> users = new ArrayList<>();
//Other details.
}

User.java


@Entity
public class User {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
private String firstName;
private String lastName;
@Convert(converter=EmailAddressConverter.class)
private EmailAddress email;
@ManyToOne
private SocialMediaSite socialMediaSite;
//Other details.
}

view raw

User.java

hosted with ❤ by GitHub

Notice that EmailAddress is  a value object.

SocialMediaRepository.java – This is a Spring Data Repository interface( a proxy instance is created via Spring to back this interface)


public interface SocialMediaSiteRepository extends JpaRepository<SocialMediaSite, Long> {
SocialMediaSite findByName(String name);
}

SocialMediaSiteEntityTest.java –  Test the JPA entities.


package com.boot.test.db;
import static org.assertj.core.api.Assertions.assertThat;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest;
import org.springframework.boot.test.autoconfigure.orm.jpa.TestEntityManager;
import org.springframework.test.context.junit4.SpringRunner;
import com.boot.entity.EmailAddress;
import com.boot.entity.SocialMediaSite;
import com.boot.entity.User;
@RunWith(SpringRunner.class)
@DataJpaTest
public class SocialMediaSiteEntityTest {
@Autowired
private TestEntityManager entityManager;
@Rule
public ExpectedException thrown = ExpectedException.none();
private SocialMediaSite facebook;
private User firstUser;
private User secondUser;
@Before
public void setUp() {
facebook = new SocialMediaSite("Facebook", "Online Social Media and Networking Service");
firstUser = new User("Mar", "Zuckerber", new EmailAddress("mark@mark.com"));
secondUser = new User("Chri", "Hughe", new EmailAddress("chris@chris.com"));
}
@Test
public void saveSocialMediaSiteFacebook() {
SocialMediaSite savedFacebookData = this.entityManager.persistAndFlush(facebook);
assertThat(savedFacebookData.getName()).isEqualTo("Facebook");
}
@Test
public void createSocialMediaSiteFacebookNullNameException() throws Exception {
this.thrown.expect(IllegalArgumentException.class);
this.thrown.expectMessage("Social Media Site Name should not be empty");
new SocialMediaSite("", "Online Social Media and Networking Service");
}
@Test
public void saveFacebookUsers() {
facebook.addUser(firstUser);
facebook.addUser(secondUser);
SocialMediaSite savedFaceBook = this.entityManager.persistFlushFind(facebook);
assertThat(savedFaceBook.getId()).isNotNull();
assertThat(savedFaceBook.getName()).isEqualTo("Facebook");
assertThat(savedFaceBook.getUsers().size()).isEqualTo(2);
}
@Test
public void removeFacebookUserChri() {
facebook.addUser(firstUser);
facebook.addUser(secondUser);
SocialMediaSite savedFaceBook = this.entityManager.persistFlushFind(facebook);
savedFaceBook.removeUser(secondUser);
SocialMediaSite updatedData = this.entityManager.persistAndFlush(savedFaceBook);
assertThat(updatedData.getUsers().size()).isEqualTo(1);
assertThat(updatedData.getUsers().get(0).getFirstName()).isEqualTo("Mar");
}
}

The setUp method annotated with the @Before annotation above initializes some mock data that we can use for the tests.

The key takeaways from this class:

  1.  @RunWith(SpringRunner .class) – This brings together JUnit and the Spring test  module. The  SpringRunner class extends SpringJUnit4ClassRunner, so it is pretty  much the  same that was used earlier. Shorter class names are always pleasing to  the eye.
  2.  @DataJpaTest   This is the most important annotation for testing JPA entities in a  Spring Boot application. It  spawns an in-memory data base and runs our tests  against it. Along with this, the  JPA entities are scanned, Transactions, Hibernate  and Spring Data are also configured.
  3.  TestEntityManager   The @DataJpaTest also configures a TestEntityManager, this  is an alternative to the EntityManager. It actually makes use of the EntityManager  but has a nice set of methods like persistAndGetId, persistAndFlush etc.
  4.  AssertJ  The code above uses the AssertJ library to perform all the assertions, this  is a nice way to get all the assertions done very fluently ! This is pulled in by the  spring-boot-starter-test dependency.
  5.  Junit – This is also pulled in by the spring-boot-starter-test dependency

On similar lines, the tests for the Repository class can also be written as shown below.

SocialMediaSiteRepositoryTest .java


package com.boot.test.db;
import static org.assertj.core.api.Assertions.assertThat;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest;
import org.springframework.test.context.junit4.SpringRunner;
import com.boot.entity.EmailAddress;
import com.boot.entity.SocialMediaSite;
import com.boot.entity.User;
import com.boot.repository.SocialMediaSiteRepository;
@RunWith(SpringRunner.class)
@DataJpaTest
public class SocialMediaSiteRepositoryTest {
@Autowired
private SocialMediaSiteRepository socialMediaSiteRepository;
private SocialMediaSite facebook;
@Before
public void setUp() {
facebook = new SocialMediaSite("Facebook", "Online Social Media and Networking Service");
}
@Test
public void saveFacebookAndFindById() {
facebook = socialMediaSiteRepository.save(facebook);
assertThat(socialMediaSiteRepository.findOne(facebook.getId())).isEqualTo((facebook));
}
@Test
public void saveFacebookAndFindBySocialMediaSiteName() {
facebook = socialMediaSiteRepository.save(facebook);
assertThat(socialMediaSiteRepository.findByName("Facebook")).isEqualTo((facebook));
}
@Test
public void saveFacebookUsers() {
User firstUser = new User("Mar", "Zuckerber", new EmailAddress("mark@mark.com"));
facebook.addUser(firstUser);
facebook = socialMediaSiteRepository.save(facebook);
// user added is not null
assertThat(socialMediaSiteRepository.findOne(facebook.getId()).getUsers()).isNotNull();
// check the one user we added.
assertThat(socialMediaSiteRepository.findOne(facebook.getId()).getUsers().size()).isEqualTo(1);
}
}

Conclusion

As you can see, testing JPA entities and the repository layer in a Spring Boot based application is quite simple. We don’t need configuration for the entire application(all layers) to test the database related functionality. Using the @DataJpaTest in Spring boot helps us in configuring and testing just the JPA section in the code.

Writing good tests for the JPA/Hibernate entities and the repository layer against an embedded database can be extremely useful in the long run. Any changes in the database schema or in the entity mapping which might lead to issues at run time can be caught immediately. In addition one can also see the SQL queries being executed which can be extremely useful.

You can find the code on github.

Note: In case you are are interested in testing JPA entities using Spring Boot 2, JUnit 5 and Java 14 , read my post here .

Getting Intimate with Spring Boot and Hibernate

In my previous blog , we looked at how to get started with a simple Spring Boot and Hibernate application. We managed to get our application up and running in a few minutes.

In this article, we will look at how and what Spring Boot does behind the scenes.

Basic requirement

To setup a Spring based application with Hibernate/JPA we usually need the following:

  1. Datasource  which connects to a database and details like the database url, password, username – this is really independent of whether we use Spring, JPA.
  2. JPA EntityManager to perform repository(CRUD) related operations.
  3. Vendor specific (Hibernate) properties
  4. Transaction support.

Let us take a look at how these things get configured.

In case of an in memory H2 database, all of the above was configured automatically by Spring Boot. We did not write a single configuration either using Java configuration or XML. Well, how does Spring Boot do everything for us?  Let’s take a look :

Vanishing (configuration) act explained :

1. The starting point is the spring.factories file. This file has a Auto Configure section which Spring Boot uses to determine what should be auto configured. This file is in the META-INF folder which is part of the spring-boot-autoconfigure-<version>.RELEASE.jar. The SpringFactoriesLoader class loads the spring.factories file.

2. Since we are talking about JPA/Hibernate, the spring.factories contains a (among other autoconfigurations) key value pair: org.springframework.boot.autoconfigure.EnableAutoConfiguration=\org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration

3. The key EnableAutoConfiguration above is triggered using the @SpringBootApplication annotation on the SpringBootJpaApplication.java file. This is our starting point in our application.


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);
}
}

4. The value part above, HibernatJpaAutoConfiguration class which is part of the Spring framework looks like


@Configuration
@ConditionalOnClass({ LocalContainerEntityManagerFactoryBean.class, EntityManager.class })
@Conditional(HibernateEntityManagerCondition.class)
@AutoConfigureAfter({ DataSourceAutoConfiguration.class })
public class HibernateJpaAutoConfiguration extends JpaBaseConfiguration {
….
}

One of the important annotations above is on line 4 :

@AutoConfigureAfter({ DataSourceAutoConfiguration.class }).

This indicates that we should perform HibernateJpaAutoConfiguration only after reading the DataSourceAutoConfiguration.class or only if a Datasource is found on the classpath. It would make no sense to configure JPA and Hibernate without a datasource/database !

5. The DataSourceAutoConfiguration looks as follows:


@Configuration
@ConditionalOnClass({ DataSource.class, EmbeddedDatabaseType.class })
@EnableConfigurationProperties(DataSourceProperties.class)
@Import({ Registrar.class, DataSourcePoolMetadataProvidersConfiguration.class })
public class DataSourceAutoConfiguration {
}

6. This is a normal Spring Configuration class which sets up the DataSource only if all of the above annotations satisfy our criteria. We used an H2 database and hence the DataSource.class and EmbeddedDatabaseType.class satisfies the condition.

7. Now the configuration moves back to step 4 where we needed the presence of  datasource/database at minimum. Now on to the next part where the following is checked :

@ConditionalOnClass({ LocalContainerEntityManagerFactoryBean.class, EntityManager.class })

This is configuration specific to JPA classes and the @ConditionalOnClass checks if these classes are there on the class path. There are present in our case through the Spring Data JPA library.

8.Next comes the @Conditional(HibernateEntityManagerCondition.class) . This checks if the JPA provider is Hibernate, this is done via the HibernateEntityManagerCondition.java. In our case it is true since Spring Boot brings in Hibernate as the default provider of JPA and HibernateEntityManager.java is on the classpath.

9.Once these conditions are satisfied, the HibernateJpaAutoConfiguration extends the JpaBaseConfiguration class.


@EnableConfigurationProperties(JpaProperties.class)
@Import(DataSourceInitializedPublisher.Registrar.class)
public abstract class JpaBaseConfiguration implements BeanFactoryAware {
}

This is annotated with the @EnableConfigurationProperties(JpaProperties.class).  This JpaProperties.class is annotated with @ConfigurationProperties(prefix = “spring.jpa”) . This gets triggered if we were to add any spring.jpa.xxx properties in our application.properties file. We would use this if we were to add any jpa specific properties. We did not add any and hence the default is assumed.

10.The JpaBaseConfiguration class contains all the other remaining configurations. It primarily uses the @ConditionalOnMissingBean annotation to configure the EntityManager, JpaVendorAdapter, LocalContainerEntityManagerFactoryBean, JpaTransactionManager if they have already not been configured. The @ConditionalOnMissingBean when applied on a method means – if this bean has not been configured, then execute the method and configure it.


@Bean
@ConditionalOnMissingBean(PlatformTransactionManager.class)
public PlatformTransactionManager transactionManager() {
JpaTransactionManager transactionManager = new JpaTransactionManager();
return transactionManager;
}

So in this way, datasource, entitymanager, vendor(hibernate) specific properties and transactions get configured. If you have setup a Spring Hibernate application before, we would do the same using Java configuration or an xml and configure the above mentioned properties. You can configure any specific properties and in that case Spring Boot will skip auto configuring that property.

Conclusion 

All the Harry Houdini illusions or Spring Boot magic starts from the spring.factories file and then through the usage of some powerful annotations like @ConditionalOnMissingBean, ConditionalOnClass,@AutoConfigureAfter , Jpa/Datasource/Transactions gets configured depending on what is found in the classpath. Spring Boot will not configure a property or a bean if it was already configured.

Complaining is a Habit ?

I have heard people complaining about the so-called magic in Spring Boot. Well, when Spring folks gave us xml configurations, we complained ! They gave us configurations via annotations and Java Configuration to get rid of the xml, we still complained ! Now, things get configured automatically…..and we still complain. Complaining can be good at times, the folks at Pivotal have been listening to our complaints and have been giving us fantastic tools/ frameworks. But let’s not forget that the details are out there, let’s explore a little more before complaining.

 

 

 

 

 

Spring Boot and Hibernate – Quick Introduction

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.

spring-boot-jpa-intializr

Dependencies

The pom.xml from the imported project contains the following important dependencies:


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

  1. 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.
  2. 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:


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)


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.


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(Stringargs) 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 :

spring-boot-sts-package

 

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:

spring-boot-sts-split-package

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.


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

Unspecified behavior of the Java Iterator

In this article we will take a look at how the behavior of the Iterator produces some surprising results if not used in the right away.

In my previous article, we saw different ways of  removing elements from an ArrayList. When we used the remove(Object o) method from the ArrayList while we traverse through the ArrayList, we get a ConcurrentModificationException. But is this always the case ?

Well, let’s consider the same example of removing a person below the age of 18 from an ArrayList but with a different data set.


package blog;
import java.util.ArrayList;
import java.util.List;
public class RemoveItemsEnhancedForModified {
private static List<Person> persons = new ArrayList<>();
private static void initialize() {
persons.add(new Person("Rahul", 25, Gender.MALE, Citizenship.INDIA));
persons.add(new Person("Sally", 21, Gender.FEMALE, Citizenship.USA));
persons.add(new Person("Ben", 35, Gender.MALE, Citizenship.CANADA));
persons.add(new Person("Wayne", 30, Gender.MALE, Citizenship.UK));
persons.add(new Person("ShaneYoung", 18, Gender.MALE, Citizenship.AUSTRALIA));
persons.add(new Person("Kimmo", 17, Gender.MALE, Citizenship.FINLAND));
persons.add(new Person("Simo", 17, Gender.MALE, Citizenship.FINLAND));
}
public static void main(String[] args) {
initialize();
removeIllegalUsingEnhancedForLoop();
System.out.println(persons);
}
private static void removeIllegalUsingEnhancedForLoop()
{
for (Person p : persons)
{
if (p.getAge() < 18)
{
persons.remove(p);
}
}
}
}

Most of the code remains the same, the only thing that has changed is the data. Notice the Person data on the 2nd last and last elements in the ArrayList.

persons.add(new Person("Kimmo", 17, Gender.MALE, Citizenship.FINLAND));
persons.add(new Person("Simo", 17, Gender.MALE, Citizenship.FINLAND));

Well, anyways, we should get a ConcurrentModificationException! Right ?

On running this the output :

[Rahul, Sally, Ben, Wayne, ShaneYoung, Simo]

Shocked ? No exception ! Not just that , Simo should have been filtered. Well, lucky Simo! He can still have beer even though he is 17.

So what is happening  ?  Why is an exception not thrown and why is the last element returned ?

The 2nd last element satisfies the filtering criteria , it gets deleted. When it gets deleted, the size of the ArrayList is reduced by 1. But, the combination of Iterating and calling remove(Object o) makes the Iterator to behave in a weird way.  When remove(Object o) is called, it makes a call to the fastRemove method which reduces the size of the list. Then there is a call to the hasNext() on the iterator to check if there are more elements to to traversed. The hasNext() looks as follows:

public boolean hasNext() {
    return cursor != size;
 }

The cursor is an index that points to the index of the next element that will be processed. It starts from 0. In our case when we delete the 2nd last element, the cursor value is 6.

Before deleting: (size =7 , cursor =6 at Simo)

Rahul
21
Sally
21
Ben
35
Wayne
30
ShaneYoung
30
Kimmo
17
Simo
  17

After deleting: (size =6 , cursor = 6 at Simo)

Rahul
21
Sally
21
Ben
35
Wayne
30
ShaneYoung
30
Simo
17

Original value of size in our list is 7. When 2nd last element(Kimmo) is deleted, size =6 , cursor = 6. The Iterator thinks all the elements have been visited. So after deleting, when hasNext() is called ( remember that an enhanced for loop still means that the Iterator is used for moving around), the above condition returns false and hence the next() is not called. The last element is completely skipped and included in the output ! Since the hasNext returns false, next() is not called and the exception is not thrown. It is the call to next() which checks for concurrent modification but it is never called.

final void checkForComodification() {
     if (modCount != expectedModCount)
    throw new ConcurrentModificationException();
 }

The Javadoc for Iterator remove method clearly states that the behavior of the iterator is unspecified if the underlying collection is modified while the iteration is in progress in any other way than by calling Iterator remove(). So the above behavior is pretty much unspecified but can catch you by surprise.

Conclusion

Read the Javadocs carefully!  I know you are religiously going to do that 🙂 !

If you are still using Java 7 or any version below that, don’t by pass the gate keeper, “The Iterator “, when simultaneously looping and deleting elements from an ArrayList. Use the remove() method from the Iterator.

Removing elements from a Java ArrayList

In this article we are going to look at the different ways of removing elements from a Java ArrayList. We will be looking at why some ways work, some might appear to work and some don’t. Finally we will look at the recommended way to remove elements from an ArrayList.

Let us assume that we have a list of Persons with name, age , gender and citizenship. Drinking below the legal age is considered a crime in most places. Let us say we want to remove these persons from the list assuming the legal age for drinking is > 18.

First Attempt – The Exceptional way

We can remove the desired elements from an ArrayList using the code below.


package blog;
import java.util.ArrayList;
import java.util.List;
public class RemoveItemsEnhancedFor
{
private static List<Person> persons = new ArrayList<>();
private static void initialize()
{
persons.add(new Person("Rahul", 25, Gender.MALE, Citizenship.INDIA));
persons.add(new Person("Sally", 21, Gender.FEMALE, Citizenship.USA));
persons.add(new Person("Ben", 35, Gender.MALE, Citizenship.CANADA));
persons.add(new Person("Wayne", 30, Gender.MALE, Citizenship.UK));
persons.add(new Person("Kimmo", 45, Gender.MALE, Citizenship.FINLAND));
persons.add(new Person("ShaneYoung", 17, Gender.MALE, Citizenship.AUSTRALIA));
}
public static void main(String[] args)
{
initialize();
removeIllegalUsingEnhancedForLoop();
System.out.println(persons);
}
private static void removeIllegalUsingEnhancedForLoop()
{
for (Person p : persons)
{
if (p.getAge() < 18)
{
persons.remove(p);
}
}
}
}

Take a look at the removeIllegalUsingEnhancedForLoop  method which uses the enhanced for loop. The initialize method adds some data to the ArrayList. Well, the code looks quite straightforward. But on running this, we get a ConcurrentModificationException.

Exception in thread "main" java.util.ConcurrentModificationException
 at java.util.ArrayList$Itr.checkForComodification(ArrayList.java:901)
 at java.util.ArrayList$Itr.next(ArrayList.java:851)
 at blog.RemoveItems.removeIllegalUsingEnhancedForLoop(RemoveItems.java:52)
 at blog.RemoveItems.main(RemoveItems.java:27)

The moment you see the word Concurrent , you are thinking, why I am getting this exception, I am not using threads ! Note that while iterating using the enhanced for loop we are also trying to remove elements, which means we are modifying the structure of the list while we are iterating. Keep in mind that we are using the <arrayList>.remove(Object o). 

But from a technical perspective, what is happening behind the scenes?

Even though we are using an enhanced for loop, there is an Iterator involved behind the scenes. The Iterator is an interface. ArrayList implements the Iterator interface via a private inner class, Itr. When we use the enhanced for loop, there is a call to a method iterator() in the ArrayList when the for loop is going to be executed.

public Iterator<E> iterator() {
 return new Itr();
 }

This Itr is the one that maintains the state of the ArrayList. It does this using 2 variables, one is the modCount and the other one is the expectedModCount. modCount is an instance variable which keeps track of the number of times the ArrayList is modified. So far we only added elements, 6 to be precise, so the modCount is 6. The Itr class maintains the expectedModCount. Since this Itr class implements Iterator interface, it provides implementation for next(), hasNext(), remove().  Note that the remove method here does not take any arguments.

When we say persons.remove(p), the ArrayList remove method which takes an object as a parameter is called and not the Itr remove(). This remove(Object o) method makes a call to fastRemove() which does increase the value of the modCount but does not touch the expectedModCount. When the element is deleted  in our case, the modCount becomes 7 but the expectedModCount is still 6. Even if you use an enhanced for loop, the elements in the ArrayList are iterated using the next, hasNext method. The next method is called as the iteration moves ahead. The next method has this piece of code :

public E next() 
 {
    checkForComodification();
    ......
 
 }
final void checkForComodification() {
 if (modCount != expectedModCount)
 throw new ConcurrentModificationException();
 }

The method next checks for modification by evaluating if modCount and expectedModCount are not equal. Since the expectedModCount has not been touched in the remove(Object o) of the ArrayList, we get this ConcurrentModificationException. In short, the ArrayList was changed without use of the Iterator.remove. It is the Iterator which maintains the internal state. We removed the element using <arrayList>.remove(Object o) leaving the Iterator puzzled, so the Iterator complains about ConcurrentModificationException. It complains that –  “Hey, you did not remove elements through me, I am the gate keeper and since you did not get your gate pass, I am going to throw an exception”.

So if this is not the right way of removing elements,  can we remove elements using an Iterator directly ?

Second Attempt – The Heavy duty Iterator way of removing elements

The Iterator has a remove method.We need to use this remove method. This is how it is done :


private static void removeIllegalUsingIterator()
{
Iterator<Person> personIterator = persons.iterator();
while (personIterator.hasNext())
{
if (personIterator.next().getAge() < 18)
{
personIterator.remove();
}
}
}

This works fine and we do not get any Exceptions. We are making use of personIterator.remove().

Why does this work ?

Itr inner class in the ArrayList implements Iterator interface.  It also maintains the correct state by increamenting modCount but also assigning expectedModCount to modCount. When we call remove() on the Iterator, not only does it increase the value of the modCount by 1 but it also does the following :

expectedModCount = modCount;

So the call to next() as shown above calls :

final void checkForComodification() {
 if (modCount != expectedModCount)
 throw new ConcurrentModificationException();
 }

This does not throw a exception as they are equal now. You got your gate pass and now the guardian of the ArrayList, the gatekeeper, the Iterator, is happy !

So obviously we must use the Iterator to remove the elements from an ArrayList while we are iterating. Well, true, if you are still stuck with Java 7. This brings us to the 3rd way of implementing removal.

Third attempt – Java 8 cute way of removing elements from an ArrayList


private static void removeIllegalUsingJava8()
{
persons.removeIf(person -> person.getAge() < 18);
}

Did you stare at the code a couple of times ? Have I missed out on showing you some code ? That is the code , yes it is ! Trust me!  You don’t ? Well, then go ahead and try it out.

The removeIf is a method added in Java 8. It has been added and has an implementation in the Collection interface. Yes, you read that right, Collection interface. It is a default method.

default boolean removeIf(Predicate<? super E> filter) {

}

This method is however overridden in the ArrayList class. It takes a Predicate which is a Functional interface. If you refer to the removeIllegalUsingJava8 method, we are passing a Lambda, person -> person.getAge() < 18. This is passed to the Predicate interface and then in the removeIf method, the test method is called. If the condition is satisfised, the element is removed. Finally the modCount is incremented to indicate that the ArrayList has gone through a modification.

So should we use this method now because it looks cute and concise ? Well that is a start. The code is short and concise, it clearly tells us it’s intention – Remove an element that satisfies this condition.

Not convinced about the cuteness – There is more to it !

The removeIf method is also more performant. What ? Cute and Efficient ? Hard to believe ? Well, the removeIf method removes and manages the elements in the ArrayList in a different was as compared to the Iterator way of removing and adjusting the elements in the ArrayList. The remove method using an Iterator uses System.arrayCopy and shifts the elements each time an element is removed from the list. This can considered as O(n^2).

The removeIf method take a different approach. It uses a BitSet class and does not use a System.arrayCopy. It creates a BitSet to maintain the index of the elements that need to be removed. It finally shifts the elements once rather than shifting them each time. So it also performs better than the Iterator remove and the performance is O(n).

Conclusion

The Java 8 removeIf way of implementing removal is not only cute but performs better. Beauty with Brains ? That is a lethal combination, I urge you to start using it!

 

Command Pattern using Java 8 Lambdas

I have been looking at how to improve my knowledge of Design Patterns and at the same time sharpen my Java 8 skills too. I have begun to realize that one can combine the two and also realized that Java 8 Lambdas are extremely powerful.

In this post, we are going to take a look at how the implementation of the Command Design Pattern can be simplified using Java 8 Lambdas.

I have written another blog where you can understand the essence of the Command Design Pattern.

The example we are going to refactor using Java 8 Lambdas is from here. This article on the tutorialspoint site refers to the typical way of implementing the pattern. You must take a look at it to get a basic understanding of the domain/problem at hand. The following is not a UML but I have shown the main components for the example mentioned.

 

CommandPatternWithoutClient

In short , BuyStock and SellStock are 2 commands which implement the Order interface. Stock is the recipient and finally the Broker is the invoker. The Broker class deals only with the Order interface and has no idea about the concrete commands.

Let us implement the same using Java 8 Lambdas. The Order interface is a Functional interface and each ConcreteCommand above is really a function. Do we really a class to represent each Command ? Well, take a look at the client code now using Lambdas:


public class CommandPatternDemo {
public static void main(String[] args) {
Stock abcStock = new Stock();
Broker broker = new Broker();
broker.takeOrder(() -> abcStock.buy());
broker.takeOrder(() -> abcStock.sell());
broker.placeOrders();
}
}

The Broker,Order interface remain the same and so does the Stock class. We can get rid of the individual Concrete Commands (BuyStock, SellStock) classes.

What we have done is actually passed behavior to the takeOrder method. This works as the Order interface has a method execute which takes no parameters and returns void. And hence () -> abcStock.buy() is a lambda expression which takes no parameters and returns void.

To understand this pattern better,  let us extend our problem. Imagine that in the same system, we had to sell Bonds too. The process of buying/selling stocks is different from bonds. With the Broker and the Order interface, the system can easily be extended with minimal changes.

NewCommandPattern

We added 2 more classes BuyBond and SellBond which implement the Order interface. These commands would invoke the Bond class( Receiver) which would perform the task of either buying or selling bonds. The Broker class remains untouched as it deals with only the Order Interface. Well, using Java 8 Lambdas, we don’t need the BuyBond or SellBond classes either.


//Client
public class CommandPatternDemo {
public static void main(String[] args) {
//Stock
Stock abcStock = new Stock();
Broker broker = new Broker();
broker.takeOrder(() -> abcStock.buy());
broker.takeOrder(() -> abcStock.sell());
//Bond
Bond bond = new Bond();
broker.takeOrder(() -> bond.buyBonds());
broker.takeOrder(() -> bond.sellBonds());
broker.placeOrders();
}
}

The Command pattern can be implemented easily using Lambdas. One could argue that the Order interface has just 1 method and we haven’t considered the undo and redo commands in the Command Design pattern. We can always fall back on the typical implementation of the pattern in case we need an undo and redo in addition to the execute functionality.

Having said that, do we always need an Order interface which acts as the Command interface ? How about using the Runnable interface instead  to run all the commands?  It could affect the readability of the code a little bit but otherwise the use of Java 8 Lambdas really makes the implementation easy and powerful at the same time.

Understanding the Command Design Pattern

Let us forget all design patterns for a moment and let us try to solve a simple problem using basic Java programming knowledge.

Problem: I would like to collect tasks to be executed later.

Let us break this down:

  1. The first part is collecting tasks –  this would mean using some kind of a storage which would add tasks together in a data structure. In Java, this can be done using  a Collection. So we need to maintain a Collection<Something>.
  2. Well a better idea would be a List<Something>. A List would be more specific.
  3. What is this Something ? It is a Task ! Okay,  a List<Task> ?
  4. That gives birth to a class Task, now we have a List<Task> to which we can add a task.
  5. Let us get more specific, let us begin with an ArrayList, this would be List<Task> tasks = new ArrayList<>()
  6. But this Task could be different types of tasks. Each “type” of Task… Each “type” of Task…List is generic, it is an interface,  ArrayList, LinkList are different “types” of List. So what next ?
  7. Refactor Task to an interface, and let each “type” of Task be a class which implements the interface Task.
  8. With this in place, we can add any type of Task to the tasks arraylist above. Task1,Task2….Taskn implements Task.
  9. As we are now done with collecting tasks, let us turn to the second part of running the tasks. The interface Task should have a method, let us call it executeTask(). Each type of Task will now override the executeTask() and perform it’s own task.
  10. To run each task – loop through each task and simply call the executeTask method.

for(Task task : tasks) {
task.executeTask();
}

In fact, the above for loop can be executed by using the Runnable interface/Thread class.

Let us turn our attention to the UML of actual Command Design Pattern :

 

Command_Pattern

Each type of Task is really a ConcreteCommand. The Command interface is really the same Task interface. The Invoker is a class which executes the for loop above and maintains a list of tasks/command. The only thing we have not seen is the Receiver, well when each Task/Command is executed, the Receiver will be invoked from each task. It is the work horse of the Command, the object that really does the work.

Advantages of using the Command Pattern:

  1. We can add ‘n’ different commands to the system later but the Invoker remains the same as it only deals with the Interface(Command/Task).
  2. Invoker is not aware of the work horse or the Receiver of each Command. So our system is extensible and loosely coupled.

This is really the essence of the Command Design Pattern.

I have written another blog where I dive into the implementation of the pattern.

Function composition using Java 8

The objective of this blog post is to give you a basic idea of functional composition in Java 8. We will look at 2 methods, andThen and compose which are part of the functional interface, Function.  We will then build on it further to show how we can apply a stream to a variable number of functions to combine all the functions.

Let us take a very simple example of 2 functions, one function adds 0.2 to an incoming value and another one adds 0.5 to an input value. So the input is a double and the output is also a double. This can represented as a Function<Double,Double>. Function is the functional interface introduced in Java 8.

Function<Double, Double> func1  =  d -> d + 0.2;
Function<Double, Double> func2  = d -> d + 0.5;

Both andThen and compose are default methods.

The andThen method:

To compose these 2 functions together , we can use andThen method from the Function interface. What do we get now ?

func1.andThen(func2)

Let us start with an initial value, 1.0.

Hence :

func1.andThen(func2).apply(1.0)

This gives us an output of 1.7.

How ?

  1. The call to the andThen method first applies the func1 to 1.0 which is the input. This gives us an output of 1.2 as behavior of func1 is d -> d+0.2, here d = 1.0
  2. The output from above , 1.2 , serves as an input to func2 and hence we get 1.2+0.5 = 1.7.

The compose method:

To understand this let us slightly modify the 2 functions:

Function<Double, Double> func1 = d -> d + 0.2;
Function<Double, Double> func2 = d -> d * 10.0;

The second function multiplies the incoming value by 10.

If we were to do:

func1.compose(func2).apply(1.0)

The output is 10.2

How?

  1. The call to the compose method first applies the func2 to 1.0 which is the input. This gives us an output of 10.0 as behavior of func2 is d -> d * 10.0, here d = 1.0
  2. The output from above , 10.0 , serves as an input to func1 and hence we get 10.0 + 0.2 = 10.2

What if we applied andThen to the above?  Well, the output is 12.0 . Surprised ?

Why?

  1. The call to the andThen method first applies the func1 to 1.0 which is the input. This gives us an output of 1.2 as behavior of func1 is d -> d+0.2, here d = 1.0
  2. The output from above , 1.2 , serves as an input to func2 and hence we get 1.2 * 10.0 = 12.0.

Remember:

The andThen method applies the first function, func1 to the input, that is the parameter to the apply method but the compose method operates by applying func2 to the value in the apply and then passes the value to func1.

andThen:

func1.andThen(func2).apply(1.0)

compose:

func1.compose(func2).apply(1.0)

More fun with functional composition:

Let us go back to :

Function<Double, Double> func1 = d -> d + 0.2;
Function<Double, Double> func2 = d -> d + 0.5;

When we did the following, we got the output as 1.7 :

func1.andThen(func2).apply(1.0)

Let us apply a Stream.of to func1 and func2.


Function<Double,Double> combined = Stream.of(func1,func2)
.reduce(Function.identity(), Function::andThen);
combined.apply(1.0);

The output from this is also 1.7

The Stream.of(…) returns a stream of Function<Double,Double>. The reduce method takes a Function.identity(), this is just saying, hey whatever is the next element in the stream, return it to me as it is. The Function::andThen specifies that combine each element in the stream with  andThen(). So <element_from_the stream>.andThen<next_element_from_stream>. The combination of stream and reduce method combines or chains all the functions together and gives us a single Function<Double,Double> which is a chain of functions.

Now how is this useful ? We can create a function which accepts  a variable number of functions and then they can all be chained in one place.


import java.util.function.Function;
import java.util.stream.Stream;
public class FunctionalChaining {
public static void main(String[] args)
{
Function<Double, Double> func1 = d -> d + 0.2;
Function<Double, Double> func2 = d -> d + 0.5;
// Simple chaining
System.out.println(func1.andThen(func2).apply(1.0));
// Chaining using Stream.of
Function<Double, Double> combined = Stream.of(func1, func2)
.reduce(Function.identity(), Function::andThen);
System.out.println(combined.apply(1.0));
// Pass it to a function which can accept variable number of functions.
System.out.println(combineFunctions(func1, func2));
}
private static Double combineFunctions(Function<Double, Double>… combineFunctions)
{
Function<Double, Double> chainedFunction = Stream.of(combineFunctions)
.reduce(function -> function,Function::andThen);
return chainedFunction.apply(1.0);
}
}

Output from all 3 types:

1.7
1.7
1.7

We used a very simple Function<Double,Double> which just added a double value but we could easily pass and chain functions which do a lot more.Function composition is a powerful mechanism which can be used to solve a variety of problems.Think about the decorator pattern or how consecutive filters are applied , can’t we use functional composition instead ?

How I met Spring Boot…

The title of this blog is inspired from the famous sitcom “How I met your Mother”. Well, this is a short story of How I met Spring Boot.

We are a team of 5 developers among whom there is a so-called “Software Architect”. In this part of the world that I live, the 2 words, “software architect” really mean different things to different people. More on that later.

There was a new requirement to rewrite a system currently maintained using mainframe to a more modern AngularJS/RESTful based application.The back-end would have REST based services which would communicate with an Oracle database using JPA . On the server side, the first task was really to set up the basic back end application and then the developers on the team would start with their use cases. Our architect decided to take up the responsibility of setting up the basic back end and mentioned that it was a tough task. By basic I mean, just the bare bones with all the basic dependencies, configuration against an in memory database to begin with, simple rest service to help the team get up and running.

When the scrum master asked him an estimate , he said he would take around 2 weeks to set up the basic backend code.

Well during the daily stand up meeting, the architect would say that he is still setting up the project and that went on for 2 weeks.At the end of 2 weeks when he checked in the code, what I saw was really shocking. What I saw was strange dependencies, outdated versions of jars, unused code,dependencies. I realized later that he had copy pasted the basic setup from another project.

Well, I said to myself, “Is setting up a project that hard ? I do remember shying away from trying a few things on my own assuming it would be complicated to bring in all the right dependencies, set up the right Spring configuration.I remember I wanted to integrate Spring with Hibernate and never really understood spring-orm library and everything else that came along with it. I have sometimes wondered how to get all configuration right and well sometimes been a little lazy.

But this time,  I decided to investigate this further and decided to set up the project  and of course nobody in the team knew this. This is when I discovered Spring Boot.

Well, as I was browsing through the official Spring framework website, I read something about bootstrapping your Spring Boot application and this is when I stumbled upon the Spring Initializr. I switched to the full version there and chose the following:

  1. Maven project
  2. Java 1.8
  3. Left the group and artifact id as it is as I was playing around.
  4. JPA support
  5. H2 as in memory database and finally
  6. Full stack web development with Tomcat and Spring MVC

And well on clicking the Generate Project button,  I had a full-fledged maven project. That took a few days…Correction – seconds!

I then wrote the following simple classes, one end point for the rest service, one for the repository layer, one JPA entity and finally the class which starts everything.

EmployeeRestController.java


package com.example;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class EmployeeRestController {
private EmployeeRepository employeeRepository;
@Autowired
public EmployeeRestController(EmployeeRepository employeeRepository) {
this.employeeRepository = employeeRepository;
}
@RequestMapping("/employees")
public List<Employee> employees() {
return employeeRepository.findAll();
}
}

EmployeeRepository.java


package com.example;
import org.springframework.data.jpa.repository.JpaRepository;
public interface EmployeeRepository extends JpaRepository<Employee, Long> {
}

Employee.java


package com.example;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
@Entity
public class Employee {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private long id;
private String firstName;
private String lastName;
public Employee() {
}
public Employee(String firstName, String lastName) {
this.firstName = firstName;
this.lastName = lastName;
}
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
@Override
public String toString() {
return "Employee [firstName=" + firstName + ", lastName=" + lastName + "]";
}
}

view raw

Employee.java

hosted with ❤ by GitHub

DemoApplication.java


package com.example;
import java.util.ArrayList;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class DemoApplication implements CommandLineRunner {
// Use constructor injection.
@Autowired
private EmployeeRepository employeeRepository;
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
// Initialization to add data to h2 db.
@Override
public void run(Stringargs) throws Exception {
List<Employee> employees = getAllEmployees();
employees.forEach(employee -> employeeRepository.save(employee));
}
private List<Employee> getAllEmployees() {
List<Employee> employees = new ArrayList<>();
employees.add(new Employee("Barney", "Stinson"));
employees.add(new Employee("Alex", "Hitch"));
employees.add(new Employee("Douglas", "Ramsey"));
return employees;
}
}

Snapshot of the pom.xml


<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.example</groupId>
<artifactId>demo</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>demo</name>
<description>Demo project for Spring Boot</description>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.4.0.RELEASE</version>
<relativePath/> <!– lookup parent from repository –>
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</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>

view raw

pom.xml

hosted with ❤ by GitHub

Then I did the following:

  1. Ran mvn clean install
  2. java -jar ./target\demo-0.0.1-SNAPSHOT.jar ( Yes, that is right, a jar file)

That’s it, the application was up and running ! When I hit the URL :

http://localhost:8080/employees

I got the following output:

[{"firstName":"Barney","lastName":"Stinson"},{"firstName":"Alex","lastName":"Hitch"},{"firstName":"Douglas","lastName":"Ramsey"}]

Note The DemoApplication implements a CommandLineRunner and hence the run method. This is being done only to populate some mock data into the H2 database which the rest service can access .

The entire thing took me only a few minutes. We were able to set up and run a Spring REST, JPA based maven project in a matter of few minutes ! Not just that , we were able to get an executable jar file which ran in an embedded server. Now, how cool is that !

Well, I wonder what the architect did during those 2 weeks what we could do in a few minutes! Not just that, we were able to configure the project with all the latest and relevant dependencies without worrying about compatibility and version related issues.

We did not write a single configuration file, there are no xml’s,  there is absolutely no code generation behind the scenes !

But what really happened ?

This is all handled by Spring Boot ! The starter pom that we added brings in the required jars to the classpath. As an example ,with the spring-boot-starter-parent and spring-boot-starter-data-jpa dependency , Sprint Boot will bring all the latest versions of the jars(Spring data, Hibernate). In our case  it pulls in version 5.0.9 of Hibernate.

Then through the usage of the @SpringBootApplication annotation (see DemoApplication.java)  Spring Boot configures  some defaults.

Some of the defaults in this case:

  1. Spring Boot configures an embedded Tomcat server if we haven’t configured it to run on anything else. This is done since we added the spring-boot-starter-web in  then pom.xml
  2. As we did not specify any other database specific parameters, Sprint boot decided to use an in memory H2 database which we added in the pom.xml
  3. Spring boot configured JPA with Hibernate for us as we added the spring-boot-starter-data-jpa dependency

Of course we can add other specific configurations that we want and in that case Spring Boot will honor that and move out of the way or if we wanted to bring an older version of Hibernate, we just need to modify the pom.xml and add the following:

<hibernate.version>Required_Version</hibernate.version>

We were able to run the application using the java -jar command. This is enabled through the spring-boot-maven-plugin dependency we added in the pom.xml.

We have only scratched the surface of how simple it is get a project up and running with a rest based service along with JPA but Spring Boot can do a lot more for us. Not only did we manage to get it up and running quickly but with all the right dependencies and the setup looks clean !

We can integrate spring boot with a nosql database, jms , apache camel, jersey, cloud foundry, service discovery and even use it to monitor the application in production. Take a look at Spring Initializr for all the cool things it can do.

This article was only meant to introduce you to Spring Boot. Well, Spring Boot is just perfect for a lazy developer like me.

Well Barney Stinson from the sitcom “How I met your mother” always wore a suit and one of his famous quote is “Suit Up”.  Having met Spring Boot, I must say that we must all Boot up…Spring Boot Up !