2017-08-06 110 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>