4

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

Jason
  • 43
  • 4
  • Honestly, I don't know if this question should get closed as a duplicate or not but the fact is that there are lots of (very) similar questions: http://stackoverflow.com/questions/2600021/1m-relationship-in-hibernate-and-cascading-operations, http://stackoverflow.com/questions/2921314/hibernate-annotated-many-to-one-not-adding-child-to-parent-collection, etc. I guess it's just hard to find them when you don't know what you're looking for. – Pascal Thivent Sep 23 '10 at 19:44
  • Thanks, Pascal! You're right; All I had was the error message, and I had no idea which direction to look for the answer. I've tried to look for solutions based on the error message but to no avail. – Jason Sep 23 '10 at 19:56
  • You made a very good point here and I now believe this question could be helpful when googling for the same "error message". – Pascal Thivent Sep 24 '10 at 01:21

1 Answers1

3

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();
Pascal Thivent
  • 562,542
  • 136
  • 1,062
  • 1,124