LaputaSpring 2010-10-08
双向一对多父子关系
保存子
Parent p=(Parent)session.load(Parent.class.pid); Child c=new Child(); c.setParent(p); p.getChildren().add(c); session.save(c); session.flush(): 为Parent添加一个addChild()方法 public void addChild(Child c){ c.setParent(this); children.add(c); } 这样上面的就可以替换为: Parent p=(Parent)session.load(Parent.class.pid); Child c=new Child(); p.addChild(c); session.save(c); session.flush(): 以上是没有使用cascade参数,要是使用cascade参数,如cascade="all",以上简化为: Parent p=(Parent)session.load(Parent.class.pid); Child c=new Child(); p.addChild(c); session.flush(): 注意这里不用显式调用save方法了,同样的,保存或删除Parent对象的时候并不需要遍历其子对象,下面的代码会删除对象 p及其所有子对象对应的数据库记录。 Parent p=(Parent)session.load(Parent.class,pid); session.delete(p); session.flush(); 然而,这段代码如下 Parent p=(Parent)session.load(Parent.class,pid); Child c=(Child)p.getChildren().iterator().next(); p.getChildren().remove(c); c.setParent(null); session.flush(); 不会从数据库删除c;它只会删除与p之间的连接(并且会导致违反NOT NULL约束,在这个例子中)。你要显式调用delete()来 删除Child。 Parent p=(Parent)session.load(Parent.class.pid); Child c=(Child)p.getChildren().iterator().next(); p.getChildren.remove(c); session.delete(c); session.flush();
在我们的例子中,如果没有父对象,子对象就不应该存在,如果将子对象从Colletction中移除,实际上我们是想删除它。
注意:即使在Collection一方的映射中指定inverse="true",级联仍然是通过遍历Collection中的元素来处理的。如果你想
通过级联进行子对象的插入、删除、更新操作,就必须把它加载到Collection中,只调用setParent()是不够的。//parentandchildwherebothloadedinaprevioussession
parent.addChild(child);//把父关联的子上,把子关联到父上.
ChildnewChild=newChild();
parent.addChild(newChild);
session.update(parent);
session.flush();
这对于自动分配标识符的情况是非常好的,但是要是自定义的,即id的子元素<generator class="assigned" />,这就比较麻级联更新:第一次是保存,以后是更新,则
Parentp=(Parent)session.getCascade(Parent.class,pid);
if(p.getChildren().size()>0){
for(Iteratoriter=p.getChildren().iterator();iter.hasNext();){
//若更新对象
Childc=(Child)iter.next();
c.setName("c");//获取子类信息}
}else{
Child c=new Child();}