Wednesday 18 September 2019

Spring data: Add custom functionality to a spring data repository


Sometimes the default queries and annotated queries may not satisfy our needs. In these case, we may need to add custom methods to the spring data repository. Spring Data allows to add custom data methods to the repository.

How can we add custom methods to a repository?
Step 1: Create an interface with custom methods.
public interface EmployeeCustomRepository {
         List<Employee> emps(List<Integer> empIds);
}

Step 2: Implement custom repository.
@Repository
public class EmployeeCustomRepositoryImpl implements EmployeeCustomRepository {

         @Override
         public List<Employee> emps(List<Integer> empIds) {
                  .....
                  .....
         }

}

Step 3: Make sure that the spring data repository extends the custom repository.

public interface EmployeeRepository extends JpaRepository<Employee, Integer>, EmployeeCustomRepository{

}

Find the below working application.

Employee.java
package com.sample.app.entity;

import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Table;

@Entity
@Table(name = "employees")
public class Employee {
 
 @Id
 private int id;
 private String firstName;
 private String lastName;

 public Employee() {
 }

 public Employee(int id, String firstName, String lastName) {
  this.id = id;
  this.firstName = firstName;
  this.lastName = lastName;
 }

 public int getId() {
  return id;
 }

 public void setId(int id) {
  this.id = id;
 }

 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 [id=" + id + ", firstName=" + firstName + ", lastName=" + lastName + "]";
 }

}


EmployeeCustomRepository.java
package com.sample.app.repository;

import java.util.List;

import com.sample.app.entity.Employee;

public interface EmployeeCustomRepository {
 List<Employee> emps(List<Integer> empIds);
}


EmployeeCustomRepositoryImpl.java
package com.sample.app.repository.impl;

import java.util.List;

import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;

import org.springframework.stereotype.Repository;

import com.sample.app.entity.Employee;
import com.sample.app.repository.EmployeeCustomRepository;

@Repository
public class EmployeeCustomRepositoryImpl implements EmployeeCustomRepository {

 @PersistenceContext
 EntityManager entityManager;

 @SuppressWarnings("unchecked")
 @Override
 public List<Employee> emps(List<Integer> empIds) {

  Query query = entityManager.createNativeQuery("SELECT * FROM employees e WHERE e.id IN " + inQuery(empIds),
    Employee.class);

  return query.getResultList();
 }

 private static final String inQuery(List<Integer> empIds) {
  StringBuilder builder = new StringBuilder();

  builder.append("(");

  for (int id : empIds) {
   builder.append(id).append(",");
  }

  String str = builder.toString();

  String result = str.substring(0, str.length() - 1) + ")";
  return result;
 }

}


App.java
package com.sample.app;

import java.util.Arrays;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;

import com.sample.app.entity.Employee;
import com.sample.app.repository.EmployeeRepository;

@SpringBootApplication
public class App {
 
 @Autowired
 EmployeeRepository empRepo;
 
 public static void main(String args[]) {
  SpringApplication.run(App.class, args);
 }

 @Bean
 public CommandLineRunner demo(EmployeeRepository employeeRepository) {
  return (args) -> {
   Employee emp1 = new Employee(1, "Lahari", "Gurram");
   Employee emp2 = new Employee(2, "bala", "Ponnam");
   Employee emp3 = new Employee(3, "Chandu", "Dondapati");
   Employee emp4 = new Employee(4, "Sudheer", "Ganji");
   Employee emp5 = new Employee(5, "Shankari", "Sri");
   
   empRepo.saveAll(Arrays.asList(emp1, emp2, emp3, emp4, emp5));
   
   empRepo.emps(Arrays.asList(2, 3, 5)).forEach(System.out::println);;
   
   
  };
 }
}


application.properties
logging.level.root=WARN
logging.level.org.hibernate=ERROR

## H2 specific properties
spring.h2.console.enabled=true
spring.h2.console.path=/h2

spring.datasource.url=jdbc:h2:file:~/db/myOrg.db;DB_CLOSE_ON_EXIT=FALSE;DB_CLOSE_DELAY=-1;

spring.datasource.username=krishna
spring.datasource.password=password123

spring.datasource.driverClassName=org.h2.Driver

## JPA specific properties
# Creates the schema, destroying previous data.
spring.jpa.hibernate.ddl-auto=create

spring.jpa.database-platform=org.hibernate.dialect.H2Dialect

spring.jpa.show-sql=true
spring.jpa.properties.hibernate.format_sql=true

## Database connection pooling properties
# Number of ms to wait before throwing an exception if no connection is available.
spring.datasource.max-wait=10000

# Maximum number of active connections that can be allocated from this pool at the same time.
spring.datasource.tomcat.max-active=10
spring.datasource.tomcat.max-idle=5
spring.datasource.tomcat.min-idle=3


pom.xml
<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>springCRUDInMemory</groupId>
 <artifactId>springCRUDInMemory</artifactId>
 <version>1</version>

 <parent>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-parent</artifactId>
  <version>2.1.6.RELEASE</version>
 </parent>

 <name>springbootApp</name>
 <url>http://maven.apache.org</url>

 <properties>
  <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
 </properties>

 <dependencies>

  <!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-data-jpa -->
  <dependency>
   <groupId>org.springframework.boot</groupId>
   <artifactId>spring-boot-starter-data-jpa</artifactId>
  </dependency>

  <!-- https://mvnrepository.com/artifact/com.h2database/h2 -->
  <dependency>
   <groupId>com.h2database</groupId>
   <artifactId>h2</artifactId>
  </dependency>

 </dependencies>
</project>


Total project structure looks like below.
Run App.java, you can see below messages in console.

Employee [id=2, firstName=bala, lastName=Ponnam]
Employee [id=3, firstName=Chandu, lastName=Dondapati]
Employee [id=5, firstName=Shankari, lastName=Sri]

You can download complete working application from this link.


Previous                                                    Next                                                    Home

No comments:

Post a Comment