Spring Data JPA & Hibernate with Cucumber

Link to the full version of the project on GitHub:
Github SpringDataJPA

Every QA automation engineer and developer frequently encounters the challenge of retrieving records from databases. In this blog post, we will explore the implementation of working with an H2 relational database using Spring Data JPA and Hibernate libraries. We will examine how Spring simplifies code and enhances query operations, and we’ll also demonstrate how to incorporate the Cucumber framework to write effective automated tests.

By utilizing Spring Data JPA and Hibernate, we can streamline database interactions and reduce code complexity. We’ll showcase the power of these technologies by working with the H2 database, a lightweight and in-memory database solution. Additionally, we’ll leverage the Cucumber framework to execute scripts and demonstrate how this approach can be applied to writing efficient and reliable automated tests.

Join us as we dive into the world of database interaction, Spring Data JPA, Hibernate, and the Cucumber framework. Discover how these tools can revolutionize the way you work with databases and facilitate the creation of robust and maintainable test suites.

Used:

Spring Data JPA Hibernate H2 Database Cucumber Junit 5

To work with the H2 relational database using Spring Data JPA and Hibernate, you need to:

  1. Implement a controller for database queries using Spring Data JPA.
  2. Write tests in Cucumber to validate the functionality of your queries.
  3. Launch the project from the console for testing and verification.

By accomplishing these tasks, you can effectively work with the H2 database, reduce code complexity using Spring, and ensure the correctness of your database queries through automated testing.

Create a maven project and connect the necessary dependencies in pom.xml

Connecting the Spring framework’s library

            org.springframework
            spring-context
            ${spring.version}
 
 
            org.springframework
            spring-orm
            ${spring.version}
 
 
            org.springframework.data
            spring-data-jpa
            2.1.5.RELEASE
 
 
            org.springframework
            spring-test
            ${spring.version}

The Hibernate library as an implementation of the JPA will be used

            org.hibernate
            hibernate-core
            ${hibernate.version}

The driver to connect to the database

            com.h2database
            h2
            ${h2.version}

Let’s add Lombok for cleaner code, with implementation of, for example, heteros – setters via annotations.

            org.projectlombok
            lombok
            ${lombok.version}

We will use the Cucumber and Junit 5 frameworks to run the tests

            io.cucumber
            cucumber-java
            ${cucumber.version}
 
 
            io.cucumber
            cucumber-junit
            ${cucumber.version}
 
 
            io.cucumber
            cucumber-spring
            ${cucumber.version}
 
 
 
            org.junit.jupiter
            junit-jupiter-api
            ${junit.jupiter.version}
 
 
            org.junit.jupiter
            junit-jupiter-engine
            ${junit.jupiter.version}

The creation of tables and filling them with test data will be fully responsible for Spring. To do this, let’s set up the configuration file application.properies

spring.datasource.url=jdbc:h2:mem:mydb;DB_CLOSE_DELAY=-1
spring.datasource.driverClassName=org.h2.Driver
spring.datasource.username=sa
spring.datasource.password=sa
spring.jpa.hibernate.ddl-auto=none
spring.jpa.show-sql=true
em.packages.scan=ru.gotoqa
spring.jpa.database-platform=org.hibernate.dialect.H2Dialect
spring.datasource.initialization-mode=always
spring.datasource.platform=h2

The project is set up, we can move on to writing code.

@Entity annotation is used to map the PersonEntity class to the Person table. The id field is labeled @Id and @GeneratedValue, it is a primary key and its value is automatically generated.

For the Person table

@Entity
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
@Table(name = "Person", schema = "actors")
public class PersonEntity {
 
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Integer id;
 
    @Column(name = "first_name")
    private String firstName;
 
    @Column(name = "last_name")
    private String lastName;
    private Date birthday;
    private String email;
    private String phone;
    private String job;
 
}

For the Geography table, the Entity description will be augmented with a static primary key (PK) class – this value will be the unique Id key that is required for Hibernate to work correctly.

@Entity
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
@Table(name = "Geography")
public class GeographyEntity {
 
    @EmbeddedId
    private PK pk;
 
    @Basic
    private Integer population;
 
    @Basic
    private String language;
 
    @Embeddable
    @Data
    public static class PK implements Serializable {
 
        @Basic
        @Column(name = "country", insertable = false, updatable = false)
        private String country;
 
        @Basic
        @Column(name = "city", insertable = false, updatable = false)
        private String city;
    }
}

Project structure:

In the project structure, the directories serve specific purposes:

  • ru.gotoqa.config: This directory contains the Spring configuration classes, including database connection parameters and other related configurations.
  • ru.gotoqa.entity: Here, you can find the directory for mapping entities to database tables. This is where the entity classes are located.
  • ru.gotoqa.repository: The repository directory contains interfaces that extend the CrudRepository interface from Spring Data JPA. These interfaces define the data access methods for interacting with the database.
  • ru.gotoqa.service: The service directory houses the service classes responsible for transaction management. It separates the business layer from the DAO implementation in the repository, providing a clear separation of concerns.
  • ru.gotoqa.steps: This directory defines the implementation of the Cucumber framework steps. It contains the step definitions for executing the Cucumber scenarios.
  • src/test/java/resources/*.feature: This directory is where you can write the test scripts (features) for the Cucumber framework. It holds the feature files that define the behavior of the system in a human-readable format.

In this project, each layer is responsible for its specific tasks, following the textbook approach. The tests are decoupled from the services and database implementation, promoting modularity and separation of concerns. This architecture ensures that each layer can function independently and is solely responsible for its own work, resulting in a more maintainable and testable codebase.

After running the tests, we get a report in the console.

Feature: Сheck records in a db table
 
  Scenario: Check records in Person table (should be 5)
    Then get all: 5 records from Person table
 
  Scenario: Check records in Geography table (should be 4)
    Then get all: 4 records from Geography table
2 Scenarios (2 passed)
2 Steps (2 passed)
0m0,243s

In conclusion, you have learned how to work with H2 relational database using Spring Data JPA and Hibernate. By implementing a controller, writing tests with Cucumber, and launching the project from the console, you can efficiently perform database queries.

The project follows a well-structured approach, separating concerns into different layers. This enhances maintainability and scalability. The console report provides valuable insights into test results for easy analysis.

Congratulations on completing this tutorial! We hope this knowledge empowers you to work with H2 database and integrate it into your Spring projects effectively.

 

Link to the full version of the project on GitHub:
Github SpringDataJPA

Related Posts