Я использую SpringBoot 2.1.2 с Hibernate и Thymeleaf.
Когда пользователь редактирует запись (объект Person), генерируется новый Id.Поэтому вместо изменения состояния объекта создается новый объект.Другое поле остается прежним.
Отладка показывает, что отредактированная модель перемещается со страницы Thymeleaf на Controller (метод save ()) с созданным новым Id.
@Controller
public class PersonController {
@Autowired
private PersonService personService;
@GetMapping("/person-list")
public String list(final Model model) {
final Collection<Person> persons = personService.findAll();
model.addAttribute("persons", persons);
return "person-list";
}
@GetMapping("/person-create")
public String create() {
personService.merge(new Person());
return "redirect:/person-list";
}
@GetMapping("/person-remove")
public String remove(@RequestParam("id") String id) {
personService.removeById(id);
return "redirect:/person-list";
}
@GetMapping("/person-edit")
public String edit(@RequestParam("id") String id, Map<String, Object> model) {
final Person person = personService.findOneById(id);
model.put("person", person);
return "person-edit";
}
@PostMapping("/person-save")
public String save(@ModelAttribute("person") Person person) {
personService.merge(person);
return "redirect:/person-list";
}
}
Исходный код страницы редактирования чабреца ниже:
<body>
<div th:replace="fragments/header.html"></div>
<form th:action="@{/person-save}" th:object="${person}" method="post">
<table width="100%" cellspacing="0" cellpadding="10" border="1">
<tr>
<td width="200" nowrap="nowrap">ID</td>
<td>
<input type="text" th:field="*{id}"/>
</td>
</tr>
<tr>
<td>First Name</td>
<td>
<input type="text" th:field="*{firstName}"/>
</td>
</tr>
<tr>
<td>Middle Name</td>
<td>
<input type="text" th:field="*{middleName}"/>
</td>
</tr>
<tr>
<td>Last Name</td>
<td>
<input type="text" th:field="*{lastName}"/>
</td>
</tr>
<tr>
<td>E-mail</td>
<td>
<input type="text" th:field="*{email}"/>
</td>
</tr>
</table>
<br/>
<button type="submit">SAVE</button>
<br/>
</form>
<div th:replace="fragments/footer.html"></div>
</body>
</html>
AbstractEntity следующим образом:
@Getter
@MappedSuperclass
public abstract class AbstractEntity {
@Id
@NotNull
@Column(name = "id")
private String id = UUID.randomUUID().toString();
}
Лицо, представленное ниже:
@Entity
@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
@Table(name = "app_persons")
@NamedQueries({
@NamedQuery(name = "Person.findAll", query = "SELECT p FROM Person p LEFT JOIN FETCH p.tasks"),
@NamedQuery(name = "Person.removeAll", query = "DELETE FROM Person p"),
@NamedQuery(name = "Person.findOneByEmail", query = "SELECT p FROM Person p WHERE p.email = :personEmail"),
@NamedQuery(name = "Person.findOne",
query = "SELECT p FROM Person p LEFT JOIN FETCH p.tasks WHERE p.id = :personId")
})
public class Person extends AbstractEntity {
@Nullable
@Column(name = "first_name")
private String firstName;
@Nullable
@Column(name = "last_name")
private String lastName;
@Nullable
@Column(name = "middle_name")
private String middleName;
@Nullable
@Column(name = "email")
private String email;
@Nullable
@OneToMany(mappedBy = "person", fetch = FetchType.LAZY)
private List<Task> tasks;
public Person(@Nullable final String firstName, @Nullable final String lastName, @Nullable final String middleName,
@Nullable final String email) {
this.firstName = firstName;
this.lastName = lastName;
this.middleName = middleName;
this.email = email;
}
@Override
public String toString() {
return lastName + " " + firstName + " " + middleName;
}
public String getShort() {
return lastName + " " + firstName;
}
public boolean isSelected(final String userId) {
if (userId == null | userId.isEmpty()) return false;
return getId().equals(userId);
}
}
Есть идеи?Заранее спасибо.