0
votes

Suppose we have standard one-to-many relationship between Parent and Child objects. In other words, one Parent holds list of Child objects.

Mapping is standard... Ids in both classes are annotated with @GeneratedValue(strategy = GenerationType.IDENTITY)... There are all getters and setters...

Parent{
    ....
    @OneToMany(cascade = CascadeType.ALL, mappedBy = "parent")
    Collection<Child> children;
    ....
}

Child{
    ...
    @ManyToOne(optional = false)
    Parent parent;
    ...
}

Child object is the owning side of relation. When I save owning Child object, and after that fetch Parent object, I expect to get previously saved Child within parent. More precise, when I execute this code:

EntityManager em... 
Parent p = new Parent();
em.persist(p);
em.flush();

Child c = new Child();
c.setParent(p);
em.persist(c);
em.flush();

Parent savedParent = em.find(Parent.class, p.getId());
savedParent.getChildren().size(); //this call returns 0 instead of 1 (why?)

...I expect that savedParent has in collection previously saved one child. But, for some reason, this does not work. Any ideas?

1

1 Answers

1
votes

By default @OneToMany has set fetch = FetchType.LAZY, set it as FetchType.EAGER.

@OneToMany(fetch = FetchType.EAGER)

UPDATE

savedParent.getChildren().size(); //this call returns 0 instead of 1 (why?)

With em.find(Parent.class, p.getId()); you are getting the entity from the First Level Cache. The Parent entity has been cached(without children) and saved in the database that's why you get 0 children. All you need to do is clean the session before calling the Parent. This will make a call to the database with your parent then savedParent.getChildren().size() must work.

EntityManager em... 
Parent p = new Parent();
em.persist(p);
em.flush();

Child c = new Child();
c.setParent(p);
em.persist(c);
em.flush();

em.clear(); //this will clear first level cache

Parent savedParent = em.find(Parent.class, p.getId()); // a sql is peformed
savedParent.getChildren().size(); //a sql is peformed for children.

PD: Be aware with the clear method, if you havent flushed yet do not call it.