Rosina
Rosina

Reputation: 125

@PostMapping with multiple RequestBody

I'm very new to Java Spring and have a little Problem.

I wan't to send the employee_id (from employees entity) to assignment entity in the body part (in Postman). Currently it's working, because I'm sending the employee_id as a PathVariable and I'm sending the assignment data with ResponseBody.

@PostMapping("/add/{employee_id}")
   public void addEmployee(@PathVariable(value = "employee_id", required = false) Long employee_id, 
             @RequestBody Assignment a) {

       Employee employeeById = employeeRepository.findById(employee_id)
               .orElseThrow(() -> new RuntimeException("Employee not found"));

       a.setEmployee(employeeById);
       assignmentRepository.addAssignment(a);
   }

It is working with the url localhost:8080/add/35. 35 is the employee_id and the assignment data can be send in the Body (of Postman). What I want to do is, to send the employee_id in the body too (so the url should only be /add), but I could not get it to work.

Like that:

{
  "employee_id": 35,
  "title": "abc"
}

Edited:

Assignment.java

public class Assignment {
   @Id
   @GeneratedValue(strategy = GenerationType.IDENTITY)
   private Integer id;

   @OneToOne(optional = false)
   @JoinColumn(name = "employee_id", nullable = false)
   private Employee employee;

   @Size(min = 3, max = 50)
   private String assignment_title;

   public Assignment() {
   }

   public Assignment(String assignment_title) {
       super();
       this.assignment_title = assignment_title;
   }

   public Integer getId() {
       return id;
   }

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

   public String getAssignment_title() {
       return assignment_title;
   }

   public void setAssignment_title(String assignment_title) {
       this.assignment_title = assignment_title;
   }

   public Employee getEmployee() {
       return employee;
   }

   public void setEmployee(Employee employee) {
       this.employee = employee;
   }
}

AssignmentService.java

   public void addAssignment(Assignment e) {
       AssignmentRepository.save(e);
   }

AssignmentRepository.java

public interface AssignmentRepository extends CrudRepository<Assignment, Integer>{
   
}

Employee.java

public class Employee{
   @Id
   @GeneratedValue(strategy = GenerationType.IDENTITY)
   private Integer id;
   
   @OneToOne(optional = false)
   @JoinColumn(name = "user_id", nullable = false)
   private User user;

   @Size(min=3, max = 100)
   private String title;

   @Size(min=3, max = 50)
   private String staff;

   private Long degree;

   public Employee() {}

   public Employee( String title, String staff, Long degree) {
       super();
       this.title = title;
       this.staff = staff;
       this.degree = degree;
   }
   
   public Integer getId() {
       return id;
   }

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

   public String getTitle() {
       return title;
   }

   public void setTitle(String title) {
       this.title = title;
   }

   public String getStaff() {
       return staff;
   }

   public void setStaff(String staff) {
       this.staff = staff;
   }

   public Long getDegree() {
       return degree;
   }

   public void setDegree(Long degree) {
       this.degree = degree;
   }

   public User getUser() {
       return user;
   }

   public void setUser(User user) {
       this.user = user;
   }

}

EmployeeRepository.java

public interface EmployeeRepository extends CrudRepository<Employee, Integer>{
   Optional<Employee> findById(Long id);
}


Thanks for your help in advance!

Upvotes: 0

Views: 760

Answers (1)

IQbrod
IQbrod

Reputation: 2265

You need to ensure your body type Assignment has such property like

public class Assignment {
    public Long employee_id;
    // ommitted
}

And get it in your method like

@PostMapping("/add")
public void addEmployee(@PathVariable(value = "employee_id", required = false) Long employee_id, @RequestBody Assignment a) {
    Long employee_id = a.employee_id;
    Employee employeeById = employeeRepository.findById(employee_id)
        .orElseThrow(() -> new RuntimeException("Employee not found"));
    a.setEmployee(employeeById);
    assignmentRepository.addAssignment(a);
}

But such implementation does not respect HTTP standards. Please consider that your actual implementation almost respect those standards and you should rename your API this way : POST URL/v1/employees/{employee_id}
This blog explains those standards

EDIT with provided specifications:

@PostMapping(values = {"/v1/employees", "/v1/employees/{employee_id}"})
public void addEmployee(@PathVariable(value = "employee_id", required = false) Long employee_id, @RequestBody Assignment a) {
    Long yourId = employee_id != null ? employee_id : a.employee_id;
    if (yourId == null) {
        throw new RuntimeException("No id given"); // Not clean either but implemented by OP
    } else {
        Employee employeeById = employeeRepository.findById(yourId)
            .orElseThrow(() -> new RuntimeException("Employee not found"));
        a.setEmployee(employeeById);
        assignmentRepository.addAssignment(a);
    }
}

As the pathvariable is optionnal you try to get it first from url and then from your body object.

EDIT 2 : An Assignment might be created with no Employee_id
First case : You accept that an Assignment might have no Employee.
Simply change your relation from Assignment to Employee :

    @OneToOne(optional = true)
    @JoinColumn(name = "employee_id", nullable = true)
    private Employee employee;

Second case : You want to create a new Employee first and then bind it to your assignement as an Assignment should always have an Employee

@PostMapping(values = {"/v1/employees", "/v1/employees/{employee_id}"})
public void addEmployee(@PathVariable(value = "employee_id", required = false) Long employee_id, @RequestBody Assignment a) {
    Long yourId = employee_id != null ? employee_id : a.employee_id;
    Employee employeeById = yourId != null ?
        employeeRepository.findById(yourId).orElseThrow(() -> new RuntimeException("Employee not found"))
        : new Employee("title","staff",2L);
    a.setEmployee(employeeById);
    assignmentRepository.addAssignment(a);
}

Upvotes: 3

Related Questions