我的程序要求是将新父级与子级一起添加到数据库中。到目前为止,我在父类中有这个方法:
@Transient
public void addLecturer(Lecturer lecturer) {
if(lecturers == null) {
lecturers = new ArrayList<Lecturer>();
}
lecturer.setChecker(this);
this.lecturers.add(lecturer);
}
然后在我的父dao中保存父级:
@Override
public void addChecker(Lecturer checker) {
Session session = sessionFactory.getCurrentSession();
session.save(checker);
}
我的控制器:
@RequestMapping(value="/matching_page", method = RequestMethod.GET)
public ModelAndView get(@ModelAttribute("checker") Lecturer checker, BindingResult
result) {
ArrayList<String> lecturers = new ArrayList<String>();
lecturers.add("Somma");
lecturers.add("Trina");
lecturers.add("Adam");
lecturers.add("Eve");
HashMap<String, ArrayList<String>> model = new HashMap<String
ArrayList<String>>();
model.put("lecturerList", lecturers);
return new ModelAndView("matching_page", "model", model);
}
@RequestMapping(value="/matching_page", method = RequestMethod.POST)
public ModelAndView hello(@ModelAttribute("checker") Lecturer checker,
BindingResult result) {
lecturerService.addChecker(checker);
return new ModelAndView ("redirect:/admin");
}
jsp表格:
<c:url var="saveUrl" value="/matching_page" />
<form:form modelAttribute="checker" method="POST" action="${saveUrl}">
<td>Checker </td>
<tr>
<td><form:hidden path="lecturerId" value="" /></td>
</tr>
<tr>
<td><form:label path="name">Checker Name:</form:label></td>
<td><form:input path="name"/></td>
</tr>
<tr>
<td><form:label path="email">Email</form:label></td>
<td><form:input path="email"/></td>
</tr>
<td>Lecturers</td>
<td>
<form:select path="name" multiple="true">
<form:option value="0" >Select </form:option>
<form:options items="${model.lecturerList}" />
</form:select>
</td>
<div id="lower">
<input type="submit" value="Save Selection" class="button"/>
</div>
</form:form>
我的数据库:
CREATE TABLE `lecturers` (
`lecturer_id` BIGINT(10) NOT NULL AUTO_INCREMENT,
`name` VARCHAR(255) NULL DEFAULT NULL,
`email` VARCHAR(255) NULL DEFAULT NULL,
`checker_id` BIGINT(20) NULL DEFAULT NULL,
PRIMARY KEY (`lecturer_id`),
FOREIGN KEY (`checker_id`) REFERENCES `lecturers` (`lecturer_id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;
我的模特
@Entity
@Table(name = "lecturers")
@Component
public class Lecturer implements Serializable{
@ManyToOne(cascade = CascadeType.ALL)
@JoinColumn(name="checker_id")
private Lecturer checker;
@OneToMany(mappedBy="checker", orphanRemoval=true)
private List<Lecturer> lecturers = new ArrayList<Lecturer>();
}
表单有一个绑定到它的父对象(检查器),我想添加一个或多个从选择列表中选择并保存的子节点。
保存有效,但它会将所有新对象保存为子节点,并且不会使用检查器ID单独保存检查器父节点。我不确定问题是什么,想知道。
答案 0 :(得分:0)
发布您的模型定义。我的猜测是,你的问题正在从你将“父母”与“孩子”联系起来的奇怪尝试中崛起。
使用hibernate,你只有有来执行一方,而hibernate将负责另一方。举个例子:
public class MyObject {
@Id
private UUID id;
@ManyToOne
@JoinColumn(name = "myColumnName")
private MyObject parent;
@OneToMany(mappedBy = "parent")
private Set<MyObject> children;
public void addChild(MyObject child) {
children.add(child);
}
public void removeChild(MyObject child) {
children.remove(child);
}
// Other Accessors
}
使用它......
public MyObject create(MyObject parent) {
// Obtain a collection of MyObject that you would like to associate as "parent's" children
for (MyObject curObject : myListOfObjects)
parent.addChild(curObject);
sessionFactory.getCurrentSession().persist(parent);
}
我实际上并没有设置来设置每个孩子的parent
,因为Hibernate会为我照顾它。我需要做的就是将每个孩子都放入父母的孩子们的集合中。如果采用非瞬态和连接的实体,则仅此行为就足以导致插入。
@Transactional
public void update(parentId,child) {
myDaoClass.readById(parentId).addChild(child);
// When the current transaction ends, hibernate will issue a commit to persist the
// child that we added (created) here. No need to call session.persist(...) on it.
// Assuming no exceptions are thrown, of course.
}