2017-08-06 111 views
1

我最近開始使用Spring Boot(我主要來自python/flask和節點背景)與JPA和thymeleaf,我試圖在我的數據庫中創建一個項目。一切進展順利,我能夠添加,刪除等。項目。無法保存實體使用百里香和彈簧啓動

我添加了一個變量設置用戶到我的項目實體,看起來像這樣:

@Entity 
@Table(name = "project") 
public class Project { 

@Id 
@GeneratedValue(strategy=GenerationType.AUTO) 
@Column(name = "project_id") 
private int id; 

@Column(name = "title") 
@NotEmpty(message = "*Please provide a title") 
private String title; 

@Column(name = "description") 
private String description; 

@OneToOne(cascade = CascadeType.ALL) 
@JoinTable(name = "project_lead", joinColumns = @JoinColumn(name = "project_id"), inverseJoinColumns = @JoinColumn(name = "user_id")) 
private User projectLead; 

@ManyToMany(cascade = CascadeType.ALL) 
@JoinTable(name = "project_user", joinColumns = @JoinColumn(name = "project_id"), inverseJoinColumns = @JoinColumn(name = "user_id")) 
private Set<User> users; 
... 
} 

用戶類看起來是這樣的:

@Entity 
@Table(name = "user") 
public class User { 

@Id 
@GeneratedValue(strategy=GenerationType.AUTO) 
@Column(name = "user_id") 
private int id; 

@Column(name = "email") 
@Email(message = "*Please provide a valid Email") 
@NotEmpty(message = "*Please provide an email") 
private String email; 

@Column(name = "username") 
@NotEmpty(message = "*Please provide a username") 
private String username; 

@Column(name = "password") 
@Length(min = 5, message = "*Your password must have at least 5 characters") 
@NotEmpty(message = "*Please provide your password") 
@Transient 
private String password; 

@Column(name = "enabled") 
private int enabled; 

@ManyToMany(cascade = CascadeType.ALL) 
@JoinTable(name = "user_role", joinColumns = @JoinColumn(name = "user_id"), inverseJoinColumns = @JoinColumn(name = "role_id")) 
private Set<Role> roles; 
... 
} 

我能當我創建新項目不要指定項目的用戶。但是當我使用多重選擇指定用戶時,我無法創建項目。在我的表單中我有:

<form th:action="@{/secure/projects}" th:object="${project}" method="POST"> 
     <div class="form-group"> 
      <label th:if="${#fields.hasErrors('title')}" th:errors="*{title}" class="validation-message"></label> 
      <input type="text" class="form-control" th:field="*{title}" id="title" th:placeholder="Title" /> 
     </div> 

     <div class="form-group"> 
      <input type="text" class="form-control" th:field="*{description}" id="description" th:placeholder="Description" /> 
     </div> 

     <div class="form-group"> 
      <select th:field="*{users}" class="users-select form-control" multiple="multiple"> 
       <option th:each="user : ${allUsers}" th:value="${user}" th:text="${user.username}"></option> 
      </select> 
     </div> 


     <button name="Submit" value="Submit" type="Submit" th:text="Create"></button> 
    </form> 

我不斷收到「未能類型的屬性值轉換‘java.lang.String中’所需類型‘爲java.util.Set’財產‘用戶’」爲次:字段= 「* {用戶}」。我不明白爲什麼th:value =「$ {user}」被認爲是一個String,當它被認爲是User類的時候。有沒有辦法讓我簡單地得到select的結果,循環遍歷它,然後手動將它添加到控制器中,以便將其添加到我的對象項目中?

我的控制器看起來是這樣的:

@RequestMapping(value = "/projects", method=RequestMethod.GET) 
public ModelAndView showProjectForm() { 
    ModelAndView modelAndView = new ModelAndView(); 
    // Get authenticated user 
    Authentication auth = SecurityContextHolder.getContext().getAuthentication(); 
    User user = userService.findByEmail(auth.getName()); 

    modelAndView.addObject("userName", "Welcome " + user.getUsername() + " (" + user.getEmail() + ")"); 
    modelAndView.addObject("project", new Project()); 
    modelAndView.addObject("allUsers", userService.findAll()); 
    modelAndView.setViewName("project_creation"); 
    return modelAndView; 
} 

@RequestMapping(value = "/projects", method=RequestMethod.POST) 
public ModelAndView processProjectForm(@Valid Project project, BindingResult bindingResult) { 
    ModelAndView modelAndView = new ModelAndView(); 
    // Get authenticated user 
    Authentication auth = SecurityContextHolder.getContext().getAuthentication(); 
    User user = userService.findByEmail(auth.getName()); 

    // Get all projects 
    List<Project> allProjects = projectService.findAll(); 

    // Check if project already exists 
    Project projectExist = projectService.findByTitle(project.getTitle()); 
    if(projectExist != null) { 
     bindingResult 
     .rejectValue("title", "error.project", 
       "There is already a project with this title"); 
    } 


    // Get all users 
    List<User> allUsers = userService.findAll(); 

    if(bindingResult.hasErrors()) { 
     modelAndView.addObject("userName", "Welcome " + user.getUsername() + " (" + user.getEmail() + ")"); 
     modelAndView.addObject("project", new Project()); 
     modelAndView.addObject("allUsers", allUsers); 
     modelAndView.setViewName("project_creation"); 
    } else { 

     // Create project 
     project.setProjectLead(user); 
     projectService.saveProject(project); 
     modelAndView.addObject("userName", "Welcome " + user.getUsername() + " (" + user.getEmail() + ")"); 
     modelAndView.addObject("success", "Project successfully created!"); 
     modelAndView.addObject("project", new Project()); 
     modelAndView.addObject("projects", allProjects); 
     modelAndView.setViewName("redirect:/secure/dashboard"); 
    } 
    return modelAndView; 
} 

回答

0

我能夠解決「無法屬性值轉換型‘java.lang.String中’所需類型‘爲java.util.Set’財產'用戶」。我只需添加一個轉換器類,告訴如何從字符串轉換爲用戶對象。

@Component 
public class StringToUser implements Converter<String, User> { 

@Autowired 
private UserService userService; 

@Override 
public User convert(String arg0) { 
    Integer id = new Integer(arg0); 
    return userService.findOne(id); 
} 
} 

並且改變了我的表單中的選項,使其具有user.id而不是用戶對象的值。轉換器將負責其餘的部分:

<option th:each="user : ${allUsers}" th:value="${user.getId()}" th:text="${user.getUsername()}"></option>