我在Springboot 2.1.2中使用Thymeleaf,并且Thymeleaf的th:each标签有问题。 这是我的代码:
<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>
但是,我遇到以下异常:
java.lang.IllegalStateException: Neither BindingResult nor plain target object for bean name 'addr' available as request attribute
调试器说找不到变量,但是,我确定视图有一个名为“ user”的绑定对象,因为我在前面的其他地方使用了它。
这是我的控制者和我的实体:
@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...
}
我按照教程here进行操作,每次使用与本教程之间都找不到任何区别。你能帮我吗?
更新=========================================== < / p>
这是我的UserService.getProfile(字符串电子邮件)代码:
@Override
public User getProfile(String email) {
Optional<User> res = userRepository.findById(email);
return res.isPresent() ? res.get() : null;
}
再次更新============================================= ============>
总结我到目前为止所做的事情:
1)在User类中使用FetchType.EAGER
2)通过打印addressList强制存储库检索相关的地址:
user.getAddressList().stream().forEach(x -> System.out.println(x.getLocation()));
3)删除th:each块并重新启动我的应用程序,没有例外;当我重新添加块时,我的应用再次失败...
所有这些措施似乎都没有帮助我。...
答案 0 :(得分:0)
问题毕竟与JPA不相关。问题是您如何使用th:field
。请参阅有关正确用法的文档:https://www.thymeleaf.org/doc/tutorials/2.1/thymeleafspring.html#dynamic-fields
尝试一下:
<tr th:each="addr,addrStat : ${user.addressList}">
<td><input type="text" th:value="${addr.name}" th:field="*{addressList[__${addrStat.index}__].name}"></td>
...
答案 1 :(得分:0)
您遇到此错误:-
java.lang.IllegalStateException: Neither BindingResult nor plain target object for bean name 'addr' available as request attribute
因为您在控制器上使用 @ModelAttribute
注释。
您正在尝试在提交后将名为addr
的对象发送到控制器,但是您并没有从您所在的控制器向控制器发送确切名称为addr
的对象。重新打开您请求的html页面。
这是一个使用 @ModelAttribute
注释发送对象的快速示例:-
1。)您从打开请求的HTML页面的位置所请求的控制器将是这样的:-
@RequestMapping("/test")
public String test(HttpServletRequest request,Model model){
//your code
model.addAttribute("addr",new MyTest());
return "yourRequestedPage";
}
2。)提交后,您的下一个控制器将是这样的:-
@RequestMapping("/testAfterSubmit")
public String someMethodName(@ModelAttribute("addr") MyTest myTestClass,HttpServletRequest request,Model model ) {
//your code . .
}
PS -有关@ModelAttribute的用途的更多信息,这是快速参考:-
答案 2 :(得分:0)
我以为我已经找到了问题...这非常棘手...我编辑了th:each块,现在就像:
<tr th:each="addr : ${user.addressList}">
<td><input type="text" th:value="${addr.name}"></td>
<td><input type="text" th:value="${addr.phone}"></td>
<td><input type="text" th:value="${addr.location}"></td>
<td><a th:href="@{/user/addr/del/{id}(id=${addr.id})}">del</a></td>
</tr>
您找到了区别吗?是的,我删除了th:field标签!在原始代码中,我所做的是将列表中的Address对象的属性绑定到迭代器!我想可能是只读的,所以编译器会在模型中期望一个名为“ addr”的对象,当然这会失败...
此错误警告我将修改功能和演示功能分离到各自的视图中...