Я пытаюсь обновить некоторые атрибуты объекта с тимелеафа.Spring Data MVC + Thymeleaf: объект обновления
Я сделал контроллер, который добавляет DTO к модели. Таким образом, мне не нужно отправлять ненужные атрибуты сотрудника в представление.
Эта настройка дает мне ошибку при попытке изменить атрибут Employee (нажав на кнопку редактирования на форме):
There was an unexpected error (type=Bad Request, status=400).
Validation failed for object='employeeDTO'. Error count: 2
Видимо моя установка не работает из-за даты и объектов списка У меня в моем DTO.
Как это решить? Нужно ли писать некоторые конвертеры? Как мне это сделать?
Нет ли более простого способа редактировать атрибуты сущности? Я имею в виду более простой способ, чем @SessionAttributes("employee")
, DTO, Mapper, Converter, ... Это кажется такой простой функциональностью, но я не могу заставить ее работать, и у меня есть ощущение, что я добавляю много вещей (DTO, mappers, конвертер? , ...), чтобы иметь возможность редактировать атрибут объекта.
Сущности:
@Entity
public class Employee {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String firstName;
private String lastName;
private Date birthDate;
@OneToMany(fetch = FetchType.EAGER)
private List<Car> carHistory = new ArrayList<Car>();
// constructors
// getters and setters
}
@Entity
public class Car {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Enumerated(EnumType.STRING)
private CarStatus status;
private String plate;
// constructors
// getters & setters
public enum CarStatus {
FREE, ORDERED, IN_USE, INACTIVE
}
}
Repository:
@Repository
public interface EmployeeRepository extends JpaRepository<Employee, Long> {
}
Услуги:
@Service
public class EmployeeService {
private EmployeeRepository employeeRepository;
@Autowired
public EmployeeService(EmployeeRepository employeeRepository) {
this.employeeRepository = employeeRepository;
}
public void updateEmployee(Employee employee){
employeeRepository.saveAndFlush(employee);
}
}
Сотрудник DTO:
public class EmployeeDTO implements Serializable{
private String firstName;
private String lastName;
private Date birthDate;
private List<Car> carHistory;
// getters & setters
}
DTO картостроитель:
public class EmployeeMapper {
public static Employee mapEmployeeDTOToEmployeeObject(EmployeeDTO dto, Employee employee){
employee.setFirstName(dto.getFirstName());
employee.setLastName(dto.getLastName());
employee.setBirthDate(dto.getBirthDate());
employee.setCarHistory(dto.getCarHistory());
return employee;
}
public static EmployeeDTO mapEmployeeToEmployeeObject(Employee employee){
EmployeeDTO dto = new EmployeeDTO();
dto.setFirstName(employee.getFirstName());
dto.setLastName(employee.getLastName());
dto.setBirthDate(employee.getBirthDate());
dto.setCarHistory(employee.getCarHistory());
return dto;
}
}
Conroller:
@Controller
@RequestMapping("/manage")
@SessionAttributes("employee")
public class ManageEmployeesController {
@Autowired
EmployeeService employeeService;
@RequestMapping("/employees")
public String manageEmployee(Model model){
model.addAttribute("employees", employeeService.getAllEmployees());
return "manage-employee";
}
@RequestMapping(value = "/employee/{employeeId}", method = RequestMethod.GET)
public String employeeDetails(@PathVariable("employeeId") Long id, Model model){
Employee emp = employeeService.getEmployeeById(id);
model.addAttribute("employee", EmployeeMapper.mapEmployeeToEmployeeObject(emp));
return "manage-employee-details";
}
@RequestMapping(value = "/employee/{employeeId}", method = RequestMethod.POST)
public String updateEmployeeDetails(@PathVariable("employeeId") Long id, EmployeeDTO employeeWithNewValues){
Employee currentEmployee = employeeService.getEmployeeById(id);
employeeService.updateEmployee(EmployeeMapper.mapEmployeeDTOToEmployeeObject(employeeWithNewValues, currentEmployee));
return "redirect:/fleetmanager/employees";
}
}
Thymeleaf форма:
<form role="form" method="post" th:object="${employee}">
<h2>Personal details</h2>
<table>
<tr>
<td>First name:</td>
<td>
<input type="text" th:readonly="true" th:value="*{firstName}" th:field="*{firstName}"/>
</td>
</tr>
<tr>
<td>Last name:</td>
<td>
<input type="text" th:value="*{lastName}" th:field="*{lastName}"/>
</td>
</tr>
<tr>
<td>Birthdate:</td>
<td>
<input type="text" th:value="*{birthDate}" th:field="*{birthDate}"/>
</td>
</tr>
<tr th:each="car : *{carHistory}">
<td th:text="${car.plate}">Plate</td>
</tr>
</table>
<input type="submit" value="Edit"/>
</form>