#java #mysql #spring #hibernate #post
#java #mysql #весна #переход в спящий режим #Публикация
Вопрос:
Я очень новичок в Java Spring и у меня небольшая проблема.
Я не хочу отправлять employee_id (из объекта employees) в объект назначения в части тела (в Postman). В настоящее время это работает, потому что я отправляю employee_id в качестве переменной пути и отправляю данные назначения с 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);
}
Он работает с URL localhost:8080/add/35. 35 — это employee_id, и данные назначения могут быть отправлены в теле (Postman). Что я хочу сделать, так это отправить employee_id и в теле (поэтому URL должен быть только / add), но я не смог заставить его работать.
Вот так:
{
"employee_id": 35,
"title": "abc"
}
Отредактировано:
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);
}
Заранее спасибо за вашу помощь!
Ответ №1:
Вам необходимо убедиться, что ваш тип тела Assignment
обладает таким свойством, как
public class Assignment {
public Long employee_id;
// ommitted
}
И получите это в своем методе, например
@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);
}
Но такая реализация не соответствует стандартам HTTP.
Пожалуйста, учтите, что ваша фактическая реализация почти соответствует этим стандартам, и вам следует переименовать свой API таким образом : POST URL/v1/employees/{employee_id}
Этот блог объясняет эти стандарты
РЕДАКТИРОВАТЬ с предоставленными спецификациями:
@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);
}
}
Поскольку переменный путь является необязательным, вы пытаетесь получить его сначала из URL, а затем из вашего объекта body.
РЕДАКТИРОВАТЬ 2: Assignment
может быть создано без Employee_id
Первый случай: вы соглашаетесь с тем, что у назначения может не быть сотрудника.
Просто измените свое отношение с назначения на сотрудника :
@OneToOne(optional = true)
@JoinColumn(name = "employee_id", nullable = true)
private Employee employee;
Второй случай: вы хотите сначала создать нового сотрудника, а затем привязать его к своему назначению, поскольку Assignment
всегда должен иметь 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);
}
Комментарии:
1. Спасибо. Но таким образом я не могу присвоить employee_id значение null. В некоторых сценариях администратор может отказаться от добавления сотрудника в назначение. Как я могу это исправить?
2. ping @Rosina вы должны предоставить несколько сопоставлений в своем
@PostMapping
3. Таким образом, я ничего не изменил, все по-прежнему так, как в моем вопросе, я просто добавил отредактированную версию из вашего кода (переменный путь и длинный yourrid). Но я все еще получаю следующую ошибку: указанный идентификатор не должен быть нулевым!
4. Затем вы должны вызвать свой репозиторий с помощью
yourId
. И убедитесь, что оно не равно нулю перед началом.5. Таким образом, это просто выдает ошибку. Я хочу добавить назначение, даже если employee_id не задан, если его значение равно нулю. Я просто попытался поместить assignmentRepository.addAssignment(a); в функцию if. Это тоже не работает. Но я могу добавить назначение с employee_id, проблем нет