2015-09-26 79 views
0

我有验证问题在百里香。我的情况是保存具有职位和角色的员工。当验证有错误时,这两个“字段”会导致LazyInitializationException。如果通过验证员工将保存到数据库,一切都可以。请给我一些建议,我做错了什么,或者我该如何解决它。Thymeleaf @Valid LazyInitializationException

请看看下面我的代码:

EmployeeController:

@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); 
    } 
} 

EmployeeForm:

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 

我会任何帮助真的很高兴。

回答

2

问题是你的休眠会话是关闭的。这个模式open-session-in-view解决了这个问题。您可以在默认情况下使用弹簧引导,或者查看fuwesta-sampe中的配置。

更简洁的方法是在关闭会话之前确保数据完整加载。这意味着服务层应该导航到每个实体或使用预先抓取。