gpt4 book ai didi

java - Spring Boot 和 Thymeleaf : Object id field is null when sending back to controller

转载 作者:塔克拉玛干 更新时间:2023-11-02 08:34:32 26 4
gpt4 key购买 nike

我正在使用 Spring MVC 和 JPA (Hibernate)。问题是,当我尝试编辑用户时,id 不会发回(null),因此存储库保存方法会创建一个新的用户对象而不是更新它。我有一个用户类,它有一个 MappedSuperClass BaseEntity。映射实现如下:

基础实体.java

@MappedSuperclass
public abstract class BaseEntity {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Version
private Long version;

protected BaseEntity() {
id = null;
}

public Long getId() {
return id;
}

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

public Long getVersion() {
return version;
}

public void setVersion(Long version) {
this.version = version;
}
}

用户.java

@Entity
public class User extends BaseEntity implements UserDetails {
@NotNull
@Size(min = 5, max = 30)
private String name;
private String username;
private LocalDate dateOfBirth;
private String address;
@JsonIgnore
private String email;
@JsonIgnore
private String password;
private String barcode;
@ManyToOne(fetch = FetchType.EAGER)
@JoinColumn(name = "role_id")
@JsonIgnore
private Role role;
@JoinTable(name = "loan", joinColumns = @JoinColumn(name = "user_id"), inverseJoinColumns = @JoinColumn(name = "book_id"))
@OneToMany(fetch = FetchType.EAGER, cascade = CascadeType.ALL)
private Set<Book> loanedBooks;

private boolean enabled;

public User() {
super();
}

public User(String name, String username, String email, String password, Role role, boolean enabled, LocalDate dateOfBirth) {
this();
this.name = name;
this.username = username;
this.email = email;
setPassword(password);
this.role = role;
this.enabled = enabled;
this.dateOfBirth = dateOfBirth;
loanedBooks = new HashSet<>();

}

@Override
public Collection<? extends GrantedAuthority> getAuthorities() {
List<GrantedAuthority> authorities = new ArrayList<>();
authorities.add(new SimpleGrantedAuthority(role.getName()));
return authorities;
}

public void loanBook(Book book) throws BookNotAvailableException{
if (book.isAvailable()) {
loanedBooks.add(book);
} else {
throw new BookNotAvailableException("Book is not available right now");
}

}

public void returnBook(Book book) {
for (Book returnBook : loanedBooks) {
if (returnBook.getBarcode().equals(book.getBarcode()));
loanedBooks.remove(returnBook);
}
}

public Set<Book> getLoanedBooks() {
return loanedBooks;
}

public void setLoanedBooks(Set<Book> loanedBooks) {
this.loanedBooks = loanedBooks;
}


public void setPassword(String password) {
this.password = password;
}

@Override
public String getPassword() {
return password;
}

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}

public String getBarcode() {
return barcode;
}

public void setBarcode(String barcode) {
this.barcode = barcode;
}

@Override
public String getUsername() {
return username;
}

public void setUsername(String username) {
this.username = username;
}

public String getEmail() {
return email;
}

public void setEmail(String email) {
this.email = email;
}

public Role getRole() {
return role;
}

public void setEnabled(boolean enabled) {
this.enabled = enabled;
}

public void setRole(Role role) {
this.role = role;
}

@Override
public boolean isAccountNonExpired() {
return true;
}

@Override
public boolean isAccountNonLocked() {
return true;
}

@Override
public boolean isCredentialsNonExpired() {
return true;
}

@Override
public boolean isEnabled() {
return enabled;
}

public LocalDate getDateOfBirth() {
return dateOfBirth;
}

public void setDateOfBirth(LocalDate dateOfBirth) {
this.dateOfBirth = dateOfBirth;
}

public String getAddress() {
return address;
}

public void setAddress(String address) {
this.address = address;
}
}

用户 Controller .java

@Controller
public class UserController {
@Autowired
UserService userService;

@GetMapping(path = "/users")
@PreAuthorize("hasAnyRole('ROLE_ADMIN','ROLE_LIBRARIAN')")
public String index(Model model) {
return "user/index";
}

// Form for editing an existing user
@RequestMapping("users/{userId}/edit")
public String formEditUser(@PathVariable Long userId, Model model) {
// TODO: Add model attributes needed for new form
if (!model.containsAttribute("user")) {
model.addAttribute("user", userService.findById(userId));
}
model.addAttribute("action", String.format("/users/%s", userId));
model.addAttribute("heading", "Edit User");
model.addAttribute("submit", "Update");
return "user/form";
}

// Update an existing user
@RequestMapping(value = "/users/{userId}", method = RequestMethod.POST)
public String updateUser(@Valid User user, BindingResult result, RedirectAttributes redirectAttributes) {
// Update user if valid data was received
if (result.hasErrors()) {
// Include validation errors upon redirect
redirectAttributes.addFlashAttribute("org.springframework.validation.BindingResult.user", result);
// Add user if invalid data was received
redirectAttributes.addFlashAttribute("user", user);
// Redirect back to the form
return String.format("redirect:/users/%s/edit", user.getId());
}

userService.save(user);

redirectAttributes.addFlashAttribute("flash", new FlashMessage("User successfully updated!", FlashMessage.Status.SUCCESS));

//Redirect browser to /users
return "redirect:/users";
}

// Form for adding a new user
@RequestMapping(value = "users/add", method = RequestMethod.GET)
public String formNewUser(Model model) {
//..
}


// Add a User
@RequestMapping(value = "/users", method = RequestMethod.POST)
public String addUser(@Valid User user, BindingResult result, RedirectAttributes redirectAttributes) {
// Add user if valid data was received
if (result.hasErrors()) {
// Include validation errors upon redirect
redirectAttributes.addFlashAttribute("org.springframework.validation.BindingResult.user", result);
// Add user if invalid data was received
redirectAttributes.addFlashAttribute("user", user);
// Redirect back to the form
return "redirect:/users/add";
}
userService.save(user);

redirectAttributes.addFlashAttribute("flash", new FlashMessage("User successfully added!", FlashMessage.Status.SUCCESS));

return "redirect:/users";
}

// Index for user search and listing
@GetMapping(path = "/users/search")
public String userSearch(@RequestParam("name_or_barcode") String nameOrBarcode,Model model) {
//..
}


// Single user page
@RequestMapping("/users/{userId}")
public String user(@PathVariable Long userId, Model model) {
User user = userService.findById(userId);
model.addAttribute("user", user);
return "user/details";
}

// Delete an existing user
@RequestMapping(value = "/users/{userId}/delete", method = RequestMethod.POST)
public String deleteUser(@PathVariable Long userId, RedirectAttributes redirectAttributes) {
User user = userService.findById(userId);

if(user.getLoanedBooks().size() > 0) {
redirectAttributes.addFlashAttribute("flash", new FlashMessage("User cannot be deleted because he/she has borrowed books",FlashMessage.Status.FAILURE));
return String.format("redirect:/users/%s/edit", userId);
}
userService.delete(user);
redirectAttributes.addFlashAttribute("flash", new FlashMessage("User deleted", FlashMessage.Status.SUCCESS));
return "redirect:/users";
}
}

用户/form.html

注意:隐藏的 id 字段在那里。

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head th:replace="layout :: head"></head>
<body>
<div th:replace="layout :: nav"></div>
<div th:replace="layout :: flash"></div>
<div class="container">
<form th:action="@{${action}}" method="post" th:object="${user}">
<input type="hidden" th:field="*{enabled}" />
<input type="hidden" th:field="*{role}" />
<input type="hidden" th:field="*{id}" />
<div class="row">
<div class="col s12">
<h2 th:text="${heading}">New User</h2>
</div>
</div>
<div class="divider"></div>
<div class="row">
<div class="col s12 l8" th:classappend="${#fields.hasErrors('name')} ? 'error' : ''">
<input type="text" th:field="*{name}" placeholder="Full Name"/>
<div class="error-message" th:if="${#fields.hasErrors('name')}" th:errors="*{name}"></div>
</div>
</div>

<div class="row">
<div class="col s12 l8">
<button th:text="${submit}" type="submit" class="button">Add</button>
<a th:href="@{/users}" class="button">Cancel</a>
</div>
</div>
</form>
<div class="row delete" th:if="${user.id != null}">
<div class="col s12 l8">
<form th:action="@{|/users/${user.id}/delete|}" method="post">
<button type="submit" class="button">Delete</button>
</form>
</div>
</div>
</div>
<div th:replace="layout :: scripts"></div>
</body>
</html>

有趣的是,启用的字段值返回为 1,这很好。

最佳答案

字段绑定(bind)看起来是正确的,除了 version 属性也必须绑定(bind)才能执行更新;否则,执行创建。考虑添加以下表单字段绑定(bind):

<input type="hidden" th:field="*{version}" />

此链接可能有用:Updating object through CRUD-Repository`s save method changes it's ID. | Treehouse Community .

希望这对您有所帮助。

关于java - Spring Boot 和 Thymeleaf : Object id field is null when sending back to controller,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45596510/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com