spring - 非空属性在添加具有外键的新用户时引用空值
问题描述
我正在尝试向数据库插入一个新用户,其中包含 userRole 的外键。我从数据库中填充了 jsp 中的角色下拉列表,插入到我将添加新用户的表单中。我现在真的被封锁了好几天......用户也有一个主键。
org.springframework.web.util.NestedServletException: Request processing failed; nested exception is org.hibernate.PropertyValueException: not-null property references a null or transient value: jpa.project.model.DemUser.idRole
@Entity
@Table(name="DEM_ROLE")
@NamedQuery(name="DemRole.findAll", query="SELECT d FROM DemRole d")
public class DemRole implements Serializable {
private static final long serialVersionUID = 1L;
private long idRole;
private String libRole;
private String librole;
public DemRole() {
}
@Id
@GeneratedValue(strategy=GenerationType.AUTO)
@Column(name="ID_ROLE", unique=true, nullable=false)
public long getIdRole() {
return this.idRole;
}
public void setIdRole(long idRole) {
this.idRole = idRole;
}
@Column(name="LIB_ROLE", nullable=false, length=50)
public String getLibRole() {
return this.libRole;
}
public void setLibRole(String libRole) {
this.libRole = libRole;
}
@Column(length=255)
public String getLibrole() {
return this.librole;
}
public void setLibrole(String librole) {
this.librole = librole;
}
}
用户实体:
@Entity
@Table(name="DEM_USER")
@NamedQuery(name="DemUser.findAll", query="SELECT d FROM DemUser d")
public class DemUser implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy=GenerationType.AUTO)
@Column(name="ID_USER", unique=true, nullable=false)
private long idUser;
@Column(name="NAME_USER", nullable=false, length=50)
private String nameUser;
@Column(nullable=false, length=20)
private String password;
//uni-directional many-to-one association to DemRole
@ManyToOne(cascade={CascadeType.ALL},fetch = FetchType.LAZY)
@JoinColumn(name="ID_ROLE", nullable=false)
private DemRole idRole;
public DemUser() {
}
public long getIdUser() {
return this.idUser;
}
public void setIdUser(long idUser) {
this.idUser = idUser;
}
public String getNameUser() {
return this.nameUser;
}
public void setNameUser(String nameUser) {
this.nameUser = nameUser;
}
public String getPassword() {
return this.password;
}
public void setPassword(String password) {
this.password = password;
}
public DemRole getIdRole() {
return this.idRole;
}
public void setIdRole(DemRole idRole) {
this.idRole = idRole;
}
}
<!-- begin snippet: js hide: false console: true babel: false -->
@RequestMapping(value = "/",method = RequestMethod.GET)
public ModelAndView home(ModelAndView model,HttpServletRequest request) throws IOException {
List<DemUser> listUsers = service.getAllUsers();
model.addObject("listUsers", listUsers);
List<DemRole> listRoles = service.getRoles();
request.setAttribute("listRoles", listRoles);
/*List<DemRole> listRoles = service.getRoles();
model.addObject("listRoles", listRoles); */
DemUser user = new DemUser();
model.addObject("DemUser", user);
model.setViewName("manageusers");
return model;
}
@RequestMapping(value = "/actionadduser", method = RequestMethod.POST)
public String actionadduser(ModelAndView model,@ModelAttribute DemRole role ,@ModelAttribute DemUser user,BindingResult result) {
service.addUser(user);
return "redirect:/";
}
<%@page contentType="text/html" pageEncoding="UTF-8"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<%@ taglib prefix="sec" uri="http://www.springframework.org/security/tags" %>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Insert title here</title>
</head>
<body>
<div align="left">
This is manage users
<table border="1">
<h1>users</h1>
<tr><td> Names : </td> </tr>
<c:forEach var="user" items="${listUsers}">
<tr>
<td>${user.nameUser}</td>
</tr>
</c:forEach>
</table>
</div>
<div align="right">
<h1>New user</h1>
<form:form action="actionadduser" method="post" modelAttribute="DemUser">
<table>
<form:hidden path="idUser" />
<form:hidden path="password" value="password" />
<tr>
<td>Name:</td>
<td><form:input path="nameUser" /></td>
</tr>
<tr>
<td>Roles :</td>
<td>
<form:select path="idRole">
<form:options items="${listRoles}" itemValue="idRole" itemLabel="libRole"></form:options>
</form:select></td>
</tr>
<tr>
<td colspan="2" align="center"><input type="submit" value="Save"></td>
</tr>
</table>
</form:form>
</div>
</body>
</html>
解决方案
有几点,
- 由于角色在添加新用户之前已经存在,因此您不需要在 @ManyToOne 映射中进行任何类型的级联,您可以完全删除级联。
//uni-directional many-to-one association to DemRole
@ManyToOne
@JoinColumn(name="ID_ROLE", nullable=false)
private DemRole idRole;
- 我可以在您的 POST 方法中看到,您正在接收 DemRole 和 DemUser 并调用服务类来持久化用户,但我看不到您将接收到的角色对象填充到接收到的用户对象中的任何地方。由于用户有角色对象,所以在保存用户对象之前,你需要有这样的东西,
@RequestMapping(value = "/actionadduser", method = RequestMethod.POST)
public String actionadduser(ModelAndView model,@ModelAttribute DemRole role ,@ModelAttribute DemUser user,BindingResult result) {
// set role object to user object
user.setIdRole(role); // setter for DemRole object.
service.addUser(user);
return "redirect:/";
}
希望这会有所帮助,如果需要更多说明,请告诉我。
推荐阅读
- json - 将带有不可预测键值对对象数组的 JSON 转换为 CSV
- c# - C#如何在字符串的最后一个斜杠之前添加文本?
- javascript - 在传单画布层上强制重绘
- go - 使用 golang 创建多个 UDP 服务器
- android - Firebase动态链接与动态参数?
- c# - OnTriggerEnter() 和 OnCollisionEnter() 不适用于角色控制器
- verilog - 我想在 Quartus2 Verilog 中进行类型转换
- sql-server - 在子查询中聚合按位或*分区*?
- python-3.x - 如何使用 pygerrit2 REST api 获取当前的补丁集信息?
- postgresql - 如何清除托管在 aws rds 中的 postgres 中的缓冲区缓存?