Reputation: 43
Let's say an Owner has a collection of Watch(es).
I am trying to create Watches and add the newly created Watches to an existing Owner's collection of watches (an arraylist).
My method is as follows:
public void add(String ownerName, String watchName) {
Owner o = new OwnerDAO().retrieve(ownerName); //retrieves owner object without fail
EntityManager em = EMF.get().createEntityManager();
EntityTransaction t = em.getTransaction();
Watch w = new Watch(watchName);
Owner owner = em.merge(o);
t.begin();
owner.getWatches().add(w);
t.commit();
em.close();
}
The code works in the local GAE environment without problem, but gave the following problem when it is on the online GAE environment:
org.datanucleus.store.mapped.scostore.FKListStore$1 fetchFields: Object "package.Owner@2b6fc7" has a collection "package.Owner.watches" yet element "package.Watch@dcc4e2" doesnt have the owner set. Managing the relation and setting the owner
.
May I know how could I solve this problem? Thank you!
The entities:
Owner:
@id
private String name;
@OneToMany(mappedBy = "owner",
targetEntity = Watch.class, cascade = CascadeType.ALL)
private List<Watch> watches= new ArrayList<Watch>();
Watch:
@id
private String name;
@ManyToOne()
private Owner owner;
Thank you very much in advance!
Warmest Regards,
Jason
Upvotes: 4
Views: 1508
Reputation: 570385
Your association is bidirectional but you're not setting both sides of the link properly, as reported by the error message. Your code should be:
...
owner.getWatches().add(w);
w.setOwner(owner); //set the other side of the relation
t.commit();
A typical pattern is to use defensive link management methods to correctly set both sides of the association, like this (in Owner
):
public void addToWatches(Watch watch) {
watches.add(watch);
watch.setOwner(this);
}
And your code would become:
...
owner.addToWatches(w);
t.commit();
Upvotes: 3