我正在尝试创建2个表,其中第一个表具有主键,而另一个表具有它的键。我正在使用Spring mvc + hibernate,并且在提交jsp表单时显示了此错误:
尝试从空的一对一属性[model.TableB.resource]分配ID;嵌套的异常是org.hibernate.id.IdentifierGenerationException:尝试从空的一对一属性[model.TableB.resource]分配ID
表A:
@Entity
public class TableA{
@Id
private String sNum
@OneToOne(mappedBy = "resource",cascade = CascadeType.ALL)
private TableB tableB;
//other fields, getter setters
}
表B:
@Entity
public class TableB{
@Id
private String id
@MapsId
@OneToOne
@JoinColumn(name="resourceId")
private TableA resource;
//other fields, getter setters
}
这些实体将以下内容输出到mysql中:
TableA
+------+---------------+---------------+-----------------+
| sNum | column1tableA | column2tableA | ..other columns |
+------+---------------+---------------+-----------------+
| PK | | | |
+------+---------------+---------------+-----------------+
TableB
+-------------------+---------+-----------------+
| resourceId | column1 | ..other columns |
+-------------------+---------+-----------------+
| PK FK from TableA | | |
+-------------------+---------+-----------------+
服务:
public class tableAService {
@Autowired
TableARepository tableARepository; //this repository extends from jpa repository
public void create(TableA tableA){
tableARepository.save(tableA);
}
}
控制器:
@RequestMapping(value = "/createTableA", method = RequestMethod.GET)
public String getCreateTableAPage(Model model){
if(!model.containsAttribute("tableA"))
model.addAttribute("tableA", new TableA());
return "createTableA";
} // this returns the registration page
@RequestMapping(value="/doCreateRe", method = RequestMethod.POST)
public String doCreateRe(@Valid @ModelAttribute("tableA") TableA tableA, BindingResult result){
if(result.hasErrors()){
return "redirect:/createPage";
}try{
myservice.create(tableA);
return "viewPage";
}catch(Exception e){
System.out.println(e.getMessage());
return "error";
}
} // this handles the onsubmit of the registration page
EDIT-2(请参阅下面的示例输出):提交表单时,应将表A的字符串ID(由用户手动在表单上输入)保存为表B上的外键。例如,我想保存一个tableA类型的对象,我将在jsp表单上手动为其分配ID,填充同一页面/表单上的其他tableA字段以及相关的tableB对象(即tableA.tableB。 someField)也存在于表单上(提交“ registration”表单后,它将在表A和表B上创建新行,表B的键将是表A的键-见下文)
createTableA页面的JSP:
<form:form modelAttribute="tableA" method="POST" action="doCreateRe">
...
<form:input path="sNum" required="true"/> <!-- sample input is abc123 -->
<form:input path="column1tableA" required="true"/> <!-- sample input is chocolate -->
<form:input path="column2tableA" required="true"/> <!-- sample input is beer -->
<form:input path="tableB.column1" required="true"/> <!-- sample input is isDelicious -->
<form:input path="tableB.column2" required="true"/> <!-- sample input is isBetter -->
...
</form:form>
提交表单后应显示在数据库中的输出:
表A:
+------------+---------------+---------------+
| sNum | column1tableA | column2tableA |
+------------+---------------+---------------+
| abc123 PK | chocolate | beer |
+------------+---------------+---------------+
表B:
+------------+-------------+----------+
| resourceId | column1 | column2 |
+------------+-------------+----------+
| abc123 FK | isDelicious | isBetter |
+------------+-------------+----------+
好吧,我终于找到了解决办法。供参考
在TableA实体上,我需要为其设置器添加额外的一行。
@Entity
public class TableA{
@Id
private String sNum
@OneToOne(mappedBy = "resource",cascade = CascadeType.ALL)
private TableB tableB;
public TableB getTableB() {
return tableB;
}
public void setTableB(TableB tableB) {
this.tableB = tableB;
tableB.setResource(this); // added this line of code
}
//other fields, getter setters
}
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句