Spring Boot Data JPA- beginner guide

Databases form an integral part of computer applications. With it comes considerable amount of database operations and the corresponding code. For huge applications which have large number of tables/entities, these operations or the code is repeated and duplicated to a large extent. Eventually a programmer would like to reduce this duplicate code. Spring framework took up the challenge and provided us with a solution in the form of Spring Data JPA.

Spring Data is one of the most useful feature released by Spring team. JPA stands for Java Persistence API.

Spring Data JPA provides repository abstraction. This means that the common or repetitive code for the repository is generated by Spring data. The programmer need not write that code again and again for all the repositories.
Thus using Spring Data reduces the boilerplate code from persistence layers.

Features of Spring Data can be listed as

  • The Spring Data generates implementation. That means we do not need to implement DAO manually anymore
  • Spring Data JPA reduces the boilerplate code required by JPA
  • That helps to implement persistence layer easier and faster
  • The DAO implementations to be completely removed

Spring Data JPA can be used with a normal Spring application as well as a Spring boot application. We shall look at both ways further in this blog.

4 steps to configure Spring Data JPA:

  1. Extend Repository interface
  2. Declare query methods in the interface
  3. Set up Spring for instantiating these interfaces
  4. Inject these instances for use

1) Extend Repository interface

In order to use Spring data with JPA, our repository or DAO interface must extend JPA specific repository interface.

This will enable Spring data to find our interface and automatically create implementation for it. Thus, our DAO interface can extend Repository interface, JpaRepository interface or any of its sub interface.

Extending sub interface indirectly extends Repository interface.

The Repository interface is the most important interface in Spring Data. It is marker interface. Repository interface takes Domain class and id type as generic type arguments.

Syntax: public interface Repository<T, ID>

T- Domain type, ID- id data type

Example for use of Repository interface

interface StudentRepository extends Repository<Student, Long> { … }

There are some sub interfaces provided by spring data for additional functionalities. Some of the sub interfaces are,

  • public interface CrudRepository<T, ID>: It provides basic CRUD functionalities.
    eg: interface StudentRepository extends CrudRepository<Student, Long> { … }
  • public interface PagingAndSortingRepository<T, ID>: this interface provides paging and sorting functionalities in addition to CRUD operations.
    eg: interface StudentRepository extends PagingAndSortingRepository <Student, Long> { … }

2) Declare query methods on the interface

Once we have created the interface for our entity, it’s time to create methods. As discussed, Spring data JPA has a feature that implements repository methods for us. All we have to do is tell Spring data what methods we need.

2 ways to define method in spring data JPA

  1. By deriving the query from the method name 
  2. Manual query using “@Query” annotation

2.1) By deriving the query from the method name

It is as straight forward as the name suggests. All we need to do is, name the method in such a way that it tells what exactly the method wants.

For instance, If we want to fetch data for the Student with department id.
The corresponding method name will be like, 

List<Student> findByDepartmentId(Long departmentId);

As we can see that the method is in plain English and easy to understand.

Assume a Student has a Department object. In Department we have id. In that case, the method creates the property traversal student.department.id.

This method will create following query

select * from Student where departmentId = ?1;

In general our interface will look like below,

interface StudentRepository extends Repository<Student, Long> {
   List<Student> findByDepartmentId(Long departmentId);
}

For this purpose, Spring data has reserved some key words such as, the prefixes find_By, read_By, query_By, count_By, and get_By in the method.

We can also use the keywords such as AND and OR to create qurey with multiple properties of an entity. We also get support for operators such as Between, LessThan, GreaterThan, and Like for the property expressions.

These supported operators can vary by database of choice. So consulting the appropriate part of reference documentation is advised. You can read more at keywords in spring data.

2.2) Manual query using “@Query” annotation

Using meaningful method name for repository sounds very interesting, however sometimes that is not enough. Specially if we need multiple properties in queries or complex query.

We can create method but the name of the method can be very long.

List<Student> findByFirstNameAndLastNameOrderByFirstnameAsc(String firstName,String lastName);

In such cases we can use @query annotation provided by Spring Data. 

@Query("SELECT s FROM Student s WHERE s.firstName =?1 or s.lastName =?2 order by firstName asc)")
List<Student> findByName(String firstName,String lastName);

Using position based parameter (?paramPosition) could be difficult to understand and refactor. This can be avoided by using named-parameters in query. We can use “:paramName” and “@Param” annotation for parameter binding.

@Query("SELECT s FROM Student s WHERE s.firstName = :firstName or s.lastName = :lastName order by firstName asc)")
List<Student> findByName(@Param("firstName")String firstName, @Param("lastName")String lastName);

3) Configuration for spring data JPA

Spring Data JPA can be used in basic spring or spring-boot project. Also the configuration can be done using xml or java classes. For configuration using java class, we need to use @Configuration annotation.

3.1 Spring data JPA configuration in spring boot:

Spring boot is another very famous framework, which make application creation and management very fast and easy. It has auto configuration feature which provides all required dependencies and configuration. We just need to add correct dependencies.

It also auto configures Spring data and hibernate as default JPA. Also it provides all necessary configuration required for spring data according to database used. We just need to add correct database connector dependency and provide data source.

We don’t need to do other configuration unless, we need to customize it.

Spring boot configuration using application.properties

spring.datasource.url=jdbc:mysql://localhost:3306/database_name
spring.datasource.username=root 
spring.datasource.password=root

3.2 Spring data JPA configuration in non-spring boot:

To use spring data we need to configure following objects:

  1. DataSource: Database configuration- URL, username, password, driver, etc
  2. EntityManager: Most important object which binds all objects, like entity package, datasource, etc
    1. we can configure entityManager using LocalEntityManagerFactoryBean
    2. we can also configure additional properties using setJpaProperties(properties)
  3. TransactionManager: Configuration for database transaction
Configuration using java code:
@Configuration
@EnableJpaRepositories
@EnableTransactionManagement
class ApplicationConfig {

  @Bean
    public DataSource dataSource(){
        DriverManagerDataSource dataSource = new DriverManagerDataSource();
        dataSource.setUrl("jdbc:mysql://localhost:3306/database_name");
        dataSource.setUsername( "root" );
        dataSource.setPassword( "root" );
        return dataSource;
    }

  @Bean
  public LocalContainerEntityManagerFactoryBean entityManagerFactory() {

    JpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter(); 
    LocalContainerEntityManagerFactoryBean entityManager = new LocalContainerEntityManagerFactoryBean();
    entityManager.setJpaVendorAdapter(vendorAdapter);
    entityManager.setPackagesToScan("com.entity.package");
    entityManager.setDataSource(dataSource());
    return entityManager;
  }

  @Bean
  public PlatformTransactionManager transactionManager(EntityManagerFactory entityManagerFactory) {
    JpaTransactionManager txManager = new JpaTransactionManager();
    txManager.setEntityManagerFactory(entityManagerFactory);
    return txManager;
  }
}
Configuration using xml file:

Similar to java code we can configure all necessary objects in xml file

<bean id="entityManager" 
 class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean"> 
    <property name="dataSource" ref="dataSource" />
    <property name="packagesToScan" value="com.entity.package" />
    <property name="jpaVendorAdapter">
        <bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter" /> 
   </property>
 </bean>

<bean id="dataSource" 
  class="org.springframework.jdbc.datasource.DriverManagerDataSource">
    <property name="url" value="jdbc:mysql://localhost:3306/database_name" />
    <property name="username" value="root" />
    <property name="password" value="root" />
</bean>

<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
    <property name="entityManagerFactory" ref="entityManager" />
</bean>

<tx:annotation-driven />
<bean id="persistenceExceptionTranslationPostProcessor" class= 
"org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor" />

4) Inject the repository instance for use

Once all the above steps are done we are ready to use. Now we just need to instantiate and use use the interfaces.

We can do that using spring basic features like dependency injection using @Autowired annotation.

class StudentService{ 

@Autowired 
private final StudentRepository studentRepository;
  
  public List<Student> findByDepartmentId(Long departmentId) {
    return studentRepository.findByDepartmentId(departmentId);
  }
} 

Fast track reading

  • Spring Data JPA is one of the most useful feature released by Spring team
  • Using Sping data JPA repository implementation can be completely removed
  • Can be used with core spring or spring boot application
  • Should extend  JPA specific Repository interface or it’s sub interface
  • Required method can be declared using meaningful name or using @Query annotation
  • Configuration can be done using xml file or in java code

Related topics

Leave a Reply

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