Spring Hibernate插入父项和子项

时间:2013-04-22 16:05:59

标签: spring hibernate

我的程序要求是将新父级与子级一起添加到数据库中。到目前为止,我在父类中有这个方法:

  @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单独保存检查器父节点。我不确定问题是什么,想知道。

1 个答案:

答案 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.
}