开发者

Update OneToMany list after entity save in Hibernate

i have relationship:

// 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;

Now look this:

A a=new A();
// setting A

B b=new B();
// setting B
b.setA(a);

session.save(b); // this save b and a obviously

Now the "problem":

  • a.getId() -> current new id OK
  • a.getBList() -> still null...

So, why bList is not update in this case?

I tried to reload a after save, in this way:

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());

But loadedA still have a NULL bList like a.

Naturally to avoid this problem i do in thy way:

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

In this way all work good, but my question is: Why Id is correctly update after save operation and bList no? I have to query db with a select statement to reload A instance correctly?


UPDATE

I have this exception

StaleStateException: Batch update returned unexpected row count from update

when i try to saveOrUpdate entity a after deleting b from it.

// first delete old b record
Session session=HibernateUtil.getSessionFactory().getCurrent开发者_开发百科Session();
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

this two operation are not in the same method of course, are fired by gui event.

session.clear is the real solution? Im doing (probably) wrong?

update

removing session.delete(b) the problem is solved again... so, what is the corretc way? I know...im totally noob with hibernate..


When working with bi-directional associations, you have to set the link on both sides of the association:

A a = new A();
B b = new B();
a.getBList().add(b);
b.setA(a);

session.persist(b);

And actually, the common pattern is to implement defensive link management methods like this:

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);
    }

    //...
}

And the code becomes:

A a = new A();
B b = new B();
a.addBToBs(b);

session.persist(b);

This is discussed in the Hibernate Tutorial:

  • 1.2.6. Working bi-directional links


Oh... ok

session.refresh(a);

This work good... is this the solution, isn't true?

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜