I'm using Thymeleaf with springboot 2.1.2, and I have a problem with Thymeleaf's th:each tag. Here's my code:
<tr th:each="addr : ${user.addressList}">
<td><input type="text" th:value="${addr.name}" th:field="${addr.name}"></td>
<td><input type="text" th:value="${addr.phone}" th:field="${addr.phone}"></td>
<td><input type="text" th:value="${addr.location}" th:field="${addr.location}"></td>
<td><a th:href="@{/user/addr/del/{id}(id=${addr.id})}">del</a></td>
</tr>
However, I encounter the following exception:
java.lang.IllegalStateException: Neither BindingResult nor plain target object for bean name 'addr' available as request attribute
The debugger says it can't find the variable, however, I'm sure that the view has a binding object named 'user' because I use it else where in the front.
Here's my controller and my entities:
@GetMapping("/profile")
public String getProfile(HttpServletRequest request, Model model) {
HttpSession session = request.getSession(false);
String email = (String) session.getAttribute("userId");
User user = userService.getProfile(email);
model.addAttribute("user", user);
return "user/profile";
}
@Entity
public class User {
@Id
private String email;
private String userName, password;
private int pts; //积分
private int status= Flags.USER_EXIST;
@OneToMany(targetEntity = Address.class
, fetch = FetchType.LAZY, mappedBy = "user"
, cascade = {CascadeType.PERSIST,CascadeType.REMOVE})
private List<Address> addressList = new ArrayList<>();
//constructors and getters and setters below...
}
@Entity
public class Address {
@Id
@GeneratedValue //去掉这个注解会导致一系列bug
private long id;
private String name, phone, location;
@ManyToOne(targetEntity = User.class)
private User user;
//constructors and getters and setters below...
}
I follow the tutorial here and I can't find any difference between my th:each usage and the tutorial's. Could you help me?
UPDATE ============================================>
Here's my code for UserService.getProfile(String email):
@Override
public User getProfile(String email) {
Optional<User> res = userRepository.findById(email);
return res.isPresent() ? res.get() : null;
}
UPDATE again ==========================================================>
summerize what i've done so far:
1) use FetchType.EAGER in User class
2) force the repository to retrieve the relevant Address by printing the addressList:
user.getAddressList().stream().forEach(x -> System.out.println(x.getLocation()));
3) delete the th:each block and restart my app, there is no exception; when i add back the block, my app fails again...
All of these measures don't seem to help me....