2015-09-26 71 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中的配置。

更簡潔的方法是在關閉會話之前確保數據完整加載。這意味着服務層應該導航到每個實體或使用預先抓取。