H2 with Spring Boot and JPA - Tutorial
I want to add a blog feature to my reference Angular / Java application. For this I need to write and read the database.
I decided to use H2 database and access it with the Spring Repositories and JPA. Spring Boot has a lot of features to easy manage our data.
The call hierarchy for the data is the following: Web controller -> Service -> Repository
You find the complete code here (Database branch): SpringAngular2TypeScript
Here the example of the Service:
@Service
public class BlogServiceImpl implements BlogService {
@Autowired
ArticleRepository articleRepository;
@Override
@Transactional(readOnly = true)
public List<Article> getArticles() {
List<Article> articleList = new ArrayList<>();
// lambda expression
// findAll() retrieve an Iterator
// method reference ...
articleRepository.findAll().forEach(articleList::add);
// ... it is equivalent to
// articleRepository.findAll().forEach(article -> articleList.add(article));
return articleList;
}
Interesting is the Iterable object returned by the CrudRepository for the findAll() method.
It could create a surprise to who has the habit to receive a List of objects.
The iterator can easily be transformed in a list using the lambda expression forEach combined with the <a href="https://docs.oracle.com/javase/tutorial/java/javaOO/methodreferences.html" rel=“nofollow" target="_blank">method reference ::add
To test the code BlogServiceTest.java:
To fill the database for the test it’s enough to create 2 files in your resources (src/test/resources) directory.
Spring looks for those files when it starts.
With schema.sql Spring creates the database:
CREATE TABLE ARTICLE (ID INT PRIMARY KEY auto_increment, TITLE VARCHAR2(100), CONTENT TEXT)
And with import.sql Spring inserts the data:
INSERT INTO ARTICLE(TITLE, CONTENT) VALUES ('Article Example', 'Hello World from Java and H2');
INSERT INTO ARTICLE(TITLE, CONTENT) VALUES ('Blog in Angular ?', 'Maybe for fun');
@RunWith(SpringRunner.class)
@SpringBootApplication
@EnableJpaRepositories(basePackages = ("ch.javaee.demo.angular2"))
@EntityScan(basePackages = "ch.javaee.demo.angular2")
public class BlogServiceTest {
@Autowired
BlogService blogService;
@Test
public void getAllArticlesTest() {
List<Article> articleList = blogService.getArticles();
assertThat(articleList).isNotNull();
Article article = articleList.get(0);
assertThat(article).hasNoNullFieldsOrProperties();
assertThat(article.getId().equals(1L));
assertThat(article.getTitle()).isEqualTo("Article Example");
Article articleTwo = articleList.get(1);
assertThat(articleTwo).hasNoNullFieldsOrProperties();
assertThat(articleTwo.getId().equals(2L));
assertThat(articleTwo.getContent()).isEqualTo("Maybe for fun");
}
}
I had few problems to find the correct annotations combination. @SpringBootTest tried to load the WebController ending in error.
In conclusion with:
- 1 Service
- 1 'Empty' Repository
- 1 Entity
- 2 SQL files
You have your database. No configuration is needed because Spring Boot automatically recognise and configure H2.