I am new to Reactive programming. I have to develop a simple spring boot application to return a json response which contains the company details with all its sub companies and employees
Created a spring boot application (Spring Webflux + Spring data r2dbc )
Using following Database Tables to represent the Company and Sub Company and Employee relationship (it is a hierarchical relationship with Company and Sub Company where a company can have N number of sub companies, and each of these sub companies can have another N number of sub companies etc and so on)
Company
- id
- name
- address
Company_SubCompany
- id
- sub_company_id (foreign key references id of above company table )
Employee
- id
- name
- designation
- company_id ( foreign key references id of above company table )
Following are the java model classes to represent the above tables
Company.java
@Data
@ToString
@AllArgsConstructor
@NoArgsConstructor
@EqualsAndHashCode
public class Company implements Serializable {
private int id;
private String name;
private String address;
@With
@Transient
private List<Company> subCompanies;
@With
@Transient
private List<Employee> employees;
}
Employee.java
@Data
@ToString
@AllArgsConstructor
@NoArgsConstructor
@EqualsAndHashCode
public class Employee implements Serializable {
@Id
private int id;
private String name;
private String designation;
}
Following repositories are created
@Repository
public interface CompanyRepository extends ReactiveCrudRepository<Company, Integer> {
@Query("select sub.sub_company_id from Company_SubCompany sub inner join Company c on sub.sub_company_id = c.id where sub.id = :id")
Flux<Integer> findSubCompnayIds(int id);
@Query("select * from Company c where id = :id")
Mono<Company> findCompanyById(Integer id);
}
@Repository
public interface EmployeeRepository extends ReactiveCrudRepository<Employee, Integer> {
@Query("select * from Employee where company_id = :id")
Flux<Employee> findEmployeeByCompanyId(Integer id);
}
In Company_SubCompany table, the super company is represented with id -1. So using this id we are now able to get the super parent company .
With the below service code i am now able to get first level of company and its employees. But i am not sure how to get all the nested sub companies and add to it
@Service
public class ComanyService {
@Autowired
CompanyRepository companyRepository;
@Autowired
EmployeeRepository employeeRepository;
public Flux<Company> findComapnyWithAllChilds() {
Flux<Integer> childCompanyIds = companyRepository.findSubCompnayIds(-1);
Flux<Company> companies = childCompanyIds.flatMap(p -> {
return Flux.zip(companyRepository.findCompanyById(p),
employeeRepository.findEmployeeByCompanyId(p).collectList(),
(t1, t2) -> t1.withEmployees(t2));
});
return companies;
}
}
I am very new to reactive, functional programing and r2dbc, so please help me to how to resolve my problem. If there is any other better approach available will use that one also. The requirement is to get the company , all its employees and sub companies (upto N leavel) .
Converter<Row, YourClass>
by implementing it our repository interface, docs.spring.io/spring-data/r2dbc/docs/1.0.x/reference/html/…, It is interesting, I will try this some time. – Stolon