我有关系:
// 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;
现在看这个:
A a=new A();
// setting A
B b=new B();
// setting B
b.setA(a);
session.save(b); // this save b and a obviously
现在是“问题”:
- a.getId() -> 当前新id OK
- a.getBList() -> 仍然为空...
那么,为什么 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());
但是 loadedA 仍然有一个像 a 的 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
这样一切都很好,但我的问题是: 为什么 Id 在保存操作后正确更新而 bList 没有? 我必须使用 select 语句查询数据库才能正确重新加载实例吗?
更新
我有这个异常(exception)
StaleStateException: Batch update returned unexpected row count from update
当我尝试在从中删除 b 后保存或更新实体 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
这两个操作当然不是在同一个方法中,是由gui事件触发的。
session.clear 才是真正的解决方案? 我(可能)做错了吗?
更新
删除 session.delete(b) 问题又解决了... 那么,正确的方法是什么? 我知道...我对 hibernate 完全是菜鸟..
最佳答案
使用双向关联时,您必须在关联的两侧 设置链接:
A a = new A();
B b = new B();
a.getBList().add(b);
b.setA(a);
session.persist(b);
实际上,常见的模式是像这样实现防御性链接管理方法:
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);
}
//...
}
代码变为:
A a = new A();
B b = new B();
a.addBToBs(b);
session.persist(b);
Hibernate 教程中对此进行了讨论:
关于java - 在 Hibernate 中保存实体后更新 OneToMany 列表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3076677/