blo*_*low 7 java orm hibernate
我有关系:
// In A.java class
@OneToMany(mappedBy="a", fetch=FetchType.LAZY)
@Cascade(CascadeType.SAVE_UPDATE)
private List<B> bList;
// In B.java class
@ManyToOne(fetch=FetchType.LAZY)
@JoinColumn(name="id_a")
@Cascade(CascadeType.SAVE_UPDATE)
private A a;
Run Code Online (Sandbox Code Playgroud)
现在看看这个:
A a=new A();
// setting A
B b=new B();
// setting B
b.setA(a);
session.save(b); // this save b and a obviously
Run Code Online (Sandbox Code Playgroud)
现在的"问题":
那么,为什么bList在这种情况下不更新?
我尝试以这种方式重新加载后保存:
A a=new A();
// setting A
B b=new B();
// setting B
b.setA(a);
session.save(b);
A loadedA=(A)session.get(A, a.getId());
Run Code Online (Sandbox Code Playgroud)
但loadedA仍然有一个像b的NULL bList.
我自然会以你的方式避免这个问题:
A a=new A();
// setting A
B b=new B();
// setting B
List<B> bList=new ArrayList<B>();
bList.add(b);
a.setBList(bList);
session.save(a); // this save a and b
Run Code Online (Sandbox Code Playgroud)
这样一切工作都很好,但我的问题是:为什么Id在保存操作后正确更新而bList没有?我必须使用select语句查询db以正确地重新加载实例?
UPDATE
我有这个例外
StaleStateException:批量更新从更新返回意外的行数
当我从中删除b后尝试saveOrUpdate实体a时.
// first delete old b record
Session session=HibernateUtil.getSessionFactory().getCurrentSession();
session.beginTransaction();
a.getBList().remove(b);
b.setA(null);
session.delete(b);
// session.clear(); // this would solve my problem, but is it correct??
session.getTransaction().commit();
// then insert new b record
Session session=HibernateUtil.getSessionFactory().getCurrentSession();
session.beginTransaction();
B b=new B();
a.getBList().add(b);
b.setA(a);
session.saveOrUpdate(a);
session.getTransaction().commit(); // this throw exception
Run Code Online (Sandbox Code Playgroud)
这两个操作当然不是同一种方法,都是由gui事件引发的.
session.clear是真正的解决方案吗?我做(可能)错了?
更新
删除session.delete(b)问题再次解决......那么,corretc方式是什么?我知道......我非常喜欢休眠...
当双向协会的工作,你必须设置链接两个协会方面:
A a = new A();
B b = new B();
a.getBList().add(b);
b.setA(a);
session.persist(b);
Run Code Online (Sandbox Code Playgroud)
实际上,常见的模式是实现这样的防御性链接管理方法:
public class A {
@OneToMany(mappedBy="a", fetch=FetchType.LAZY)
@Cascade(CascadeType.SAVE_UPDATE)
private List<B> bList = new ArrayList<B>();
protected List<B> getListB() {
return bList;
}
protected void setListB(List bList) {
this.bList = bList;
}
public void addBToBs(B b) {
bList.add(b);
b.setA(this);
}
//...
}
Run Code Online (Sandbox Code Playgroud)
代码变成:
A a = new A();
B b = new B();
a.addBToBs(b);
session.persist(b);
Run Code Online (Sandbox Code Playgroud)
这在Hibernate教程中讨论: