Monday, 15 November 2021

Spring Data: findBy query including relations

In this post, I am going to explain how to query the relations using findBy query methods.

 

For example, an employee can work on zero or more projects.

 

 


As shown in the above image,

a.   One employee can work in zero or more projects

b.   A project can be delivered by one or more employees

 

There is a many to many relationship here. To model this kind of relationship, we should create 2 document collections (employees, projects) and one edge collection (workingIn).

 

Employee.java

@Document("employees")
public class Employee {

  @Id // db document field: _key
  private String key;

  @ArangoId // db document field: _id
  private String arangoId;

  private Integer id;
  private String firstName;
  private String lastName;
  private Integer age;

  @Relations(edges = WorkingIn.class, lazy = true)
  private Collection<Project> projects;

  .....
  .....
}

Project.java

@Document("projects")
public class Project {
  @Id // db document field: _key
  private String key;

  @ArangoId // db document field: _id
  private String arangoId;

  private Integer pjtId;

  private String projectName;

  @Relations(edges = WorkingIn.class, lazy = true)
  private Collection<Employee> employees;

  ......
  ......
}

WorkingIn.java

@Edge("workingIn")
public class WorkingIn {

  @Id // db document field: _key
  private String id;

  private Integer fromYear;

  private Integer toYear;

  @ArangoId // db document field: _id
  private String arangoId;

  @From
  private Employee emp;

  @To
  private Project pjt;

  ......
  ......
}

 

How to get employees working in given project by project name?

public List<Employee> findByProjectsProjectName(String projectName);

 

Find the below working application.

 

Step 1: Create new maven project ‘find-by-relations-demo’.

 

Step 2: Update pom.xml with maven dependencies.

 

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>com.sample.app</groupId>
  <artifactId>find-by-relations-demo</artifactId>
  <version>1</version>

  <!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-parent -->
  <parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>2.4.5</version>
  </parent>


  <dependencies>
    <dependency>
      <groupId>com.arangodb</groupId>
      <artifactId>arangodb-spring-boot-starter</artifactId>
      <version>2.3.3.RELEASE</version>
    </dependency>
  </dependencies>

  <build>
    <plugins>
      <plugin>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-maven-plugin</artifactId>
      </plugin>
    </plugins>
  </build>

</project>

 

Step 3: Define entity classes.

 

Employee.java

 

package com.sample.app.entity;

import java.util.Collection;

import org.springframework.data.annotation.Id;

import com.arangodb.springframework.annotation.ArangoId;
import com.arangodb.springframework.annotation.Document;
import com.arangodb.springframework.annotation.Relations;

@Document("employees")
public class Employee {

  @Id // db document field: _key
  private String key;

  @ArangoId // db document field: _id
  private String arangoId;

  private Integer id;
  private String firstName;
  private String lastName;
  private Integer age;

  @Relations(edges = WorkingIn.class, lazy = true)
  private Collection<Project> projects;

  public Employee() {

  }

  public Employee(Integer id, String firstName, String lastName, Integer age) {
    super();
    this.id = id;
    this.firstName = firstName;
    this.lastName = lastName;
    this.age = age;
  }

  public String getKey() {
    return key;
  }

  public void setKey(String key) {
    this.key = key;
  }

  public String getArangoId() {
    return arangoId;
  }

  public void setArangoId(String arangoId) {
    this.arangoId = arangoId;
  }

  public Integer getId() {
    return id;
  }

  public void setId(Integer 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;
  }

  public Integer getAge() {
    return age;
  }

  public void setAge(Integer age) {
    this.age = age;
  }

  public Collection<Project> getProjects() {
    return projects;
  }

  public void setProjects(Collection<Project> projects) {
    this.projects = projects;
  }

  @Override
  public String toString() {
    return "Employee [id=" + id + ", firstName=" + firstName + ", lastName=" + lastName + ", age=" + age + "]";
  }

}

 

Project.java

package com.sample.app.entity;

import java.util.Collection;

import org.springframework.data.annotation.Id;

import com.arangodb.springframework.annotation.ArangoId;
import com.arangodb.springframework.annotation.Document;
import com.arangodb.springframework.annotation.Relations;

@Document("projects")
public class Project {
  @Id // db document field: _key
  private String key;

  @ArangoId // db document field: _id
  private String arangoId;

  private Integer pjtId;

  private String projectName;

  @Relations(edges = WorkingIn.class, lazy = true)
  private Collection<Employee> employees;

  public Project(Integer pjtId, String projectName) {
    super();
    this.pjtId = pjtId;
    this.projectName = projectName;
  }

  public String getKey() {
    return key;
  }

  public void setKey(String key) {
    this.key = key;
  }

  public String getArangoId() {
    return arangoId;
  }

  public void setArangoId(String arangoId) {
    this.arangoId = arangoId;
  }

  public Integer getPjtId() {
    return pjtId;
  }

  public void setPjtId(Integer pjtId) {
    this.pjtId = pjtId;
  }

  public String getProjectName() {
    return projectName;
  }

  public void setProjectName(String projectName) {
    this.projectName = projectName;
  }

  public Collection<Employee> getEmployees() {
    return employees;
  }

  public void setEmployees(Collection<Employee> employees) {
    this.employees = employees;
  }

  @Override
  public String toString() {
    return "Project [key=" + key + ", arangoId=" + arangoId + ", pjtId=" + pjtId + ", projectName=" + projectName
        + "]";
  }

}

 

WorkingIn.java

package com.sample.app.entity;

import org.springframework.data.annotation.Id;

import com.arangodb.springframework.annotation.ArangoId;
import com.arangodb.springframework.annotation.Edge;
import com.arangodb.springframework.annotation.From;
import com.arangodb.springframework.annotation.To;

@Edge("workingIn")
public class WorkingIn {

  @Id // db document field: _key
  private String id;

  private Integer fromYear;

  private Integer toYear;

  @ArangoId // db document field: _id
  private String arangoId;

  @From
  private Employee emp;

  @To
  private Project pjt;

  public WorkingIn(Employee emp, Project pjt, Integer fromYear, Integer toYear) {
    this.emp = emp;
    this.pjt = pjt;
    this.fromYear = fromYear;
    this.toYear = toYear;
  }

  public String getId() {
    return id;
  }

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

  public String getArangoId() {
    return arangoId;
  }

  public void setArangoId(String arangoId) {
    this.arangoId = arangoId;
  }

  public Employee getEmp() {
    return emp;
  }

  public void setEmp(Employee emp) {
    this.emp = emp;
  }

  public Project getPjt() {
    return pjt;
  }

  public void setPjt(Project pjt) {
    this.pjt = pjt;
  }

  public Integer getFromYear() {
    return fromYear;
  }

  public void setFromYear(Integer fromYear) {
    this.fromYear = fromYear;
  }

  public Integer getToYear() {
    return toYear;
  }

  public void setToYear(Integer toYear) {
    this.toYear = toYear;
  }

  @Override
  public String toString() {
    return "WorkingIn [id=" + id + ", fromYear=" + fromYear + ", toYear=" + toYear + ", arangoId=" + arangoId
        + ", emp=" + emp + ", pjt=" + pjt + "]";
  }

}

 

Step 4: Define repository interfaces.

 

EmployeeRepository.java

 

package com.sample.app.repository;

import java.util.List;

import com.arangodb.springframework.repository.ArangoRepository;
import com.sample.app.entity.Employee;

public interface EmployeeRepository extends ArangoRepository<Employee, String> {

  public List<Employee> findByProjectsProjectName(String projectName);

}

 

ProjectRepository.java

package com.sample.app.repository;

import com.arangodb.springframework.repository.ArangoRepository;
import com.sample.app.entity.Project;

public interface ProjectRepository extends ArangoRepository<Project, String> {

}

 

WorkingInRepository.java

package com.sample.app.repository;

import com.arangodb.springframework.repository.ArangoRepository;
import com.sample.app.entity.WorkingIn;

public interface WorkingInRepository extends ArangoRepository<WorkingIn, String>{

}

 

Step 5: Add arangoDB configuration classes.

 

ArangoConfig.java

 

package com.sample.app.config;

import org.springframework.context.annotation.Configuration;

import com.arangodb.ArangoDB;
import com.arangodb.springframework.annotation.EnableArangoRepositories;
import com.arangodb.springframework.config.ArangoConfiguration;

@Configuration
@EnableArangoRepositories(basePackages = { "com.sample.app" })
public class ArangoConfig implements ArangoConfiguration {

  @Override
  public ArangoDB.Builder arango() {
    return new ArangoDB.Builder().host("localhost", 8529).user("root").password("tiger");
  }

  @Override
  public String database() {
    return "abc_org";
  }
}

Step 6: Define main application class.

 

App.java

package com.sample.app;

import java.util.List;

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.entity.Project;
import com.sample.app.entity.WorkingIn;
import com.sample.app.repository.EmployeeRepository;
import com.sample.app.repository.ProjectRepository;
import com.sample.app.repository.WorkingInRepository;

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

  @Bean
  public CommandLineRunner demo(EmployeeRepository employeeRepo, ProjectRepository projectRepo,
      WorkingInRepository workingInRepository) {

    return (args) -> {

      Project pjt1 = new Project(1, "HPHS");
      Project pjt2 = new Project(2, "Employee management system");
      Project pjt3 = new Project(3, "Flight control system");

      pjt1 = projectRepo.save(pjt1);
      pjt2 = projectRepo.save(pjt2);
      pjt3 = projectRepo.save(pjt3);

      Employee emp1 = new Employee(1, "Ram", "Gurram", 31);
      Employee emp2 = new Employee(2, "Rudra", "Gurram", 32);
      Employee emp3 = new Employee(3, "Gopi", "Battu", 31);
      Employee emp4 = new Employee(4, "Joel", "Chelli", 32);
      Employee emp5 = new Employee(5, "Sailu", "Ptr", 31);
      Employee emp6 = new Employee(6, "Lahari", "Gurram", 23);

      emp1 = employeeRepo.save(emp1);
      emp2 = employeeRepo.save(emp2);
      emp3 = employeeRepo.save(emp3);
      emp4 = employeeRepo.save(emp4);
      emp5 = employeeRepo.save(emp5);
      emp6 = employeeRepo.save(emp6);

      WorkingIn workingInd1 = new WorkingIn(emp1, pjt1, 2009, null);
      WorkingIn workingInd2 = new WorkingIn(emp1, pjt2, 2008, 2019);
      WorkingIn workingInd3 = new WorkingIn(emp2, pjt1, 2013, 2021);
      WorkingIn workingInd4 = new WorkingIn(emp3, pjt3, 2018, null);
      WorkingIn workingInd5 = new WorkingIn(emp4, pjt3, 2008, 2013);
      WorkingIn workingInd6 = new WorkingIn(emp5, pjt1, 2011, 2013);

      workingInRepository.save(workingInd1);
      workingInRepository.save(workingInd2);
      workingInRepository.save(workingInd3);
      workingInRepository.save(workingInd4);
      workingInRepository.save(workingInd5);
      workingInRepository.save(workingInd6);

      System.out.println("Employees working in the project HPHS");
      List<Employee> emps = employeeRepo.findByProjectsProjectName("HPHS");

      for (Employee emp : emps) {
        System.out.println(emp);
      }
    };
  }
}

Total project structure looks like below.



Run App.java, you will see below messages in console.

Employees working in the project HPHS
Employee [id=1, firstName=Ram, lastName=Gurram, age=31]
Employee [id=2, firstName=Rudra, lastName=Gurram, age=32]
Employee [id=5, firstName=Sailu, lastName=Ptr, age=31]

 

You can download complete working application from below link.

https://github.com/harikrishna553/springboot/tree/master/arangodb/find-by-relations-demo

 


Previous                                                    Next                                                    Home

No comments:

Post a Comment