【问题标题】:Spring Hibernate inserting parent along with childrenSpring Hibernate 将父级和子级一起插入
【发布时间】:2013-04-22 16:05:58
【问题描述】:

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

  @Transient
public void addLecturer(Lecturer lecturer) {
    if(lecturers == null) {
        lecturers = new ArrayList<Lecturer>();
        }
    lecturer.setChecker(this);

    this.lecturers.add(lecturer);
 }

然后在我的 parent dao 中保存 parent:

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

【问题讨论】:

  • 您说它将所有新对象保存为子对象...但是当父对象(检查器)不是时,它怎么能做到这一点(这意味着它们有一个父对象,因此是 checker_id 的值) t 也保存了吗?

标签: spring hibernate


【解决方案1】:

发布您的模型定义。我的猜测是,您的问题源于您将“父母”与其“孩子”联系起来的奇怪尝试。

使用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.
}

【讨论】:

  • 感谢您的回复。我现在正在考虑你的建议。与此同时,我编辑了我的问题以添加模型。这是一节课。
  • 模型看起来不错。我相信您有其他数据(电子邮件、姓名等)的 id 列和列注释,并且为了简洁起见将它们剪掉?
猜你喜欢
  • 2012-07-13
  • 1970-01-01
  • 2012-09-03
  • 1970-01-01
  • 2018-01-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-10-08
相关资源
最近更新 更多