Thymeleaf @Valid LazyInitializationException
Thymeleaf @Valid LazyInitializationException
我在 thymeleaf 中遇到验证问题。我的案例是用 Position 和 Role-s 保存 Employee。当验证有错误时,这两个 "fields" 会导致 LazyInitializationException。如果验证通过,员工将被保存到数据库,一切正常。请给我一些建议,我做错了什么或者我该如何解决。
请在下面查找我的代码:
雇员控制器:
@Controller
public class EmployeeController extends BaseCrudController {
// (........)
@RequestMapping(value = urlFragment + "/create", method = RequestMethod.GET)
public String createEmployee(Model model) {
prepareEmployeeForm(model);
return "crud/employee/create";
}
@RequestMapping(value = urlFragment + "/create", method = RequestMethod.POST)
public String processNewEmployee(Model model, @ModelAttribute("employeeForm") @Valid EmployeeForm employeeForm, BindingResult result) {
if (!result.hasErrors()) {
User user = employeeFormService.getUserFromEmployeeForm(employeeForm);
try {
userService.merge(user);
model.addAttribute("success", true);
prepareEmployeeForm(model);
} catch (Exception e) {
model.addAttribute("error", true);
}
} else {
initCollections(employeeForm, model);
}
return "crud/employee/create";
}
private void initCollections(EmployeeForm employeeForm, Model model)
{
employeeForm.setAllAvailableRoles(roleRepository.findAll());
employeeForm.setAllAvailablePositions(positionRepository.findByEnabledTrueOrderByNameAsc());
model.addAttribute("employeeForm", employeeForm);
}
private void prepareEmployeeForm(Model model) {
EmployeeForm employee = new EmployeeForm();
employee.setAllAvailablePositions(positionRepository.findByEnabledTrueOrderByNameAsc());
employee.setAllAvailableRoles(roleRepository.findAll());
model.addAttribute("employeeForm", employee);
}
}
雇员表格:
public class EmployeeForm extends BaseForm {
@Length(min = 2, max = 45)
private String firstName = "";
// (........)
private Position position;
private Collection<Role> roles;
private Collection<Position> allAvailablePositions;
private Collection<Role> allAvailableRoles;
public EmployeeForm() {
}
public Position getPosition() {
return position;
}
public void setPosition(Position position) {
this.position = position;
}
public Collection<Role> getRoles() {
return roles;
}
public void setRoles(Collection<Role> roles) {
this.roles = roles;
}
public Collection<Position> getAllAvailablePositions() {
return allAvailablePositions;
}
public void setAllAvailablePositions(Collection<Position> allAvailablePositions) {
this.allAvailablePositions = allAvailablePositions;
}
public Collection<Role> getAllAvailableRoles() {
return allAvailableRoles;
}
public void setAllAvailableRoles(Collection<Role> allAvailableRoles) {
this.allAvailableRoles = allAvailableRoles;
}
}
employeeForm.html
<form action="#" th:action="@{/panel/employee/create}" th:object="${employeeForm}" method="post">
<!--(......)-->
<div class="row">
<div class="col-md-6">
<label th:text="#{position}">Position</label>
<!--(Line 57 cause LazyInitializationException)--><select th:field="*{position}" class="form-control">
<option th:each="positionQ : *{allAvailablePositions}"
th:value="${{positionQ}}"
th:text="${positionQ.name}">Position name
</option>
</select>
</div>
<div class="col-md-6">
<label th:text="#{permissions}">Permissions</label>
<th:block th:each="role : *{allAvailableRoles}">
<p>
<input type="checkbox" th:id="${{role}}" th:value="${{role}}" th:field="*{roles}"/>
<label th:for="${{role}}"
th:text="#{${role.name}}">Role name</label>
</p>
</th:block>
</div>
</div>
</form>
跟踪:
HTTP Status 500 - Request processing failed; nested exception is org.thymeleaf.exceptions.TemplateProcessingException: Error during execution of processor 'org.thymeleaf.spring4.processor.attr.SpringSelectFieldAttrProcessor' (crud/employee/employeeForm:57)
根本原因:
org.springframework.web.util.NestedServletException: Request processing failed; nested exception is org.thymeleaf.exceptions.TemplateProcessingException: Error during execution of processor 'org.thymeleaf.spring4.processor.attr.SpringSelectFieldAttrProcessor' (crud/employee/employeeForm:57)
根本原因
org.thymeleaf.exceptions.TemplateProcessingException: Error during execution of processor 'org.thymeleaf.spring4.processor.attr.SpringSelectFieldAttrProcessor' (crud/employee/employeeForm:57)
根本原因
org.hibernate.LazyInitializationException: could not initialize proxy - no Session
如果有任何帮助,我将非常高兴。
问题是您的休眠会话已关闭。模式 open-session-in-view 解决了这个问题。您可以使用默认的 spring-boot 或查看 fuwesta-sampe.
中的配置
更简洁的方法是确保在关闭会话之前已完成数据加载。这意味着服务层应导航到每个实体或使用预先获取。
我在 thymeleaf 中遇到验证问题。我的案例是用 Position 和 Role-s 保存 Employee。当验证有错误时,这两个 "fields" 会导致 LazyInitializationException。如果验证通过,员工将被保存到数据库,一切正常。请给我一些建议,我做错了什么或者我该如何解决。
请在下面查找我的代码:
雇员控制器:
@Controller
public class EmployeeController extends BaseCrudController {
// (........)
@RequestMapping(value = urlFragment + "/create", method = RequestMethod.GET)
public String createEmployee(Model model) {
prepareEmployeeForm(model);
return "crud/employee/create";
}
@RequestMapping(value = urlFragment + "/create", method = RequestMethod.POST)
public String processNewEmployee(Model model, @ModelAttribute("employeeForm") @Valid EmployeeForm employeeForm, BindingResult result) {
if (!result.hasErrors()) {
User user = employeeFormService.getUserFromEmployeeForm(employeeForm);
try {
userService.merge(user);
model.addAttribute("success", true);
prepareEmployeeForm(model);
} catch (Exception e) {
model.addAttribute("error", true);
}
} else {
initCollections(employeeForm, model);
}
return "crud/employee/create";
}
private void initCollections(EmployeeForm employeeForm, Model model)
{
employeeForm.setAllAvailableRoles(roleRepository.findAll());
employeeForm.setAllAvailablePositions(positionRepository.findByEnabledTrueOrderByNameAsc());
model.addAttribute("employeeForm", employeeForm);
}
private void prepareEmployeeForm(Model model) {
EmployeeForm employee = new EmployeeForm();
employee.setAllAvailablePositions(positionRepository.findByEnabledTrueOrderByNameAsc());
employee.setAllAvailableRoles(roleRepository.findAll());
model.addAttribute("employeeForm", employee);
}
}
雇员表格:
public class EmployeeForm extends BaseForm {
@Length(min = 2, max = 45)
private String firstName = "";
// (........)
private Position position;
private Collection<Role> roles;
private Collection<Position> allAvailablePositions;
private Collection<Role> allAvailableRoles;
public EmployeeForm() {
}
public Position getPosition() {
return position;
}
public void setPosition(Position position) {
this.position = position;
}
public Collection<Role> getRoles() {
return roles;
}
public void setRoles(Collection<Role> roles) {
this.roles = roles;
}
public Collection<Position> getAllAvailablePositions() {
return allAvailablePositions;
}
public void setAllAvailablePositions(Collection<Position> allAvailablePositions) {
this.allAvailablePositions = allAvailablePositions;
}
public Collection<Role> getAllAvailableRoles() {
return allAvailableRoles;
}
public void setAllAvailableRoles(Collection<Role> allAvailableRoles) {
this.allAvailableRoles = allAvailableRoles;
}
}
employeeForm.html
<form action="#" th:action="@{/panel/employee/create}" th:object="${employeeForm}" method="post">
<!--(......)-->
<div class="row">
<div class="col-md-6">
<label th:text="#{position}">Position</label>
<!--(Line 57 cause LazyInitializationException)--><select th:field="*{position}" class="form-control">
<option th:each="positionQ : *{allAvailablePositions}"
th:value="${{positionQ}}"
th:text="${positionQ.name}">Position name
</option>
</select>
</div>
<div class="col-md-6">
<label th:text="#{permissions}">Permissions</label>
<th:block th:each="role : *{allAvailableRoles}">
<p>
<input type="checkbox" th:id="${{role}}" th:value="${{role}}" th:field="*{roles}"/>
<label th:for="${{role}}"
th:text="#{${role.name}}">Role name</label>
</p>
</th:block>
</div>
</div>
</form>
跟踪:
HTTP Status 500 - Request processing failed; nested exception is org.thymeleaf.exceptions.TemplateProcessingException: Error during execution of processor 'org.thymeleaf.spring4.processor.attr.SpringSelectFieldAttrProcessor' (crud/employee/employeeForm:57)
根本原因:
org.springframework.web.util.NestedServletException: Request processing failed; nested exception is org.thymeleaf.exceptions.TemplateProcessingException: Error during execution of processor 'org.thymeleaf.spring4.processor.attr.SpringSelectFieldAttrProcessor' (crud/employee/employeeForm:57)
根本原因
org.thymeleaf.exceptions.TemplateProcessingException: Error during execution of processor 'org.thymeleaf.spring4.processor.attr.SpringSelectFieldAttrProcessor' (crud/employee/employeeForm:57)
根本原因
org.hibernate.LazyInitializationException: could not initialize proxy - no Session
如果有任何帮助,我将非常高兴。
问题是您的休眠会话已关闭。模式 open-session-in-view 解决了这个问题。您可以使用默认的 spring-boot 或查看 fuwesta-sampe.
中的配置更简洁的方法是确保在关闭会话之前已完成数据加载。这意味着服务层应导航到每个实体或使用预先获取。