4

What is appropriate way of creating objects with One-to-Many relationship using Objectify and RequestFactory? I've read documentation for these libraries, and also reviewed number of sample projects such as listwidget and gwtgae2011. All of them use @Embedded annotation which is not what I want because it stores everything within one entity. Another option according to documentation would be to use @Parent property in child classes. In my example (getters/setters removed for simplicity) I have entities Person and Organization which defined as

@Entity
public class Person extends DatastoreObject
{
    private String name;
    private String phoneNumber;
    private String email;
    @Parent private Key<Organization> organizationKey;
}

and

@Entity
public class Organization extends DatastoreObject
{
    private String name;
    private List<Person> contactPeople;
    private String address;
}

Now if I understood documentation correctly in order to persist Organization with one Person I have to persist Organization first, then set organizationKey to ObjectifyService.factory().getKey(organization) for Person object and then persist it. I already don't like that I have to iterate through every child object manually but using RequestFactory makes everything is more convoluted due to presence of proxy classes. How would I define Organization and OrganizationProxy classes - with Key<> or without it ? Will I have to define something like this in Organization ?

public void setContactPeople(List<Person> contactPeople)
{
    for (int i = 0; i < contactPeople.size(); ++i)
    {
        DAOBase dao = new DAOBase();
        Key<Organization> key = dao.ofy().put(this);
        contactPeople.get(i).setOrganizationKey(key);
    }
    this.contactPeople = contactPeople;
}

And how would I load Organization with its children from Datastore ? Will I have to manually fetch every Person and fill out Organization.contactPeople in @PostLoad method ?

It seems like I'll have to write A LOT of maintenance code just to do what JPA/JDO does behind the scene. I simply don't get it :(

Am I missing something or it's the only way to implement it ?

Thanks a lot for answers in advance!!!

expert
  • 29,290
  • 30
  • 110
  • 214
  • After even more googling and reading it seems like I have to do everything manually. Plus considering limiting parent-child relationship of google datastore which is inability to re-use child with multiple parents brings me to conclusion that all my entities would have to be root entities in Datastore's terminology. Which leads me to another thought that perhaps I should try [Twig](http://code.google.com/p/twig-persist/). – expert Oct 19 '11 at 05:20

1 Answers1

1

You need to make it as @Parent only when you going to use it in transaction against all Person in this Organization. I'm sure it's not what you want.

It's enough to save just private Key<Organization> organizationKey, and filter by this field when you need to find Person for specified Organization

As about loading all referenced objects - yes, it is, you have to load it manually. It's pita, but it's not a lot of code.

Also, there is a different way to store this relationship, if your organization are small enough, and consists of few hundreds of people. At this case you can have List<Key<Person>> contactPeopleKey;, and load all this people by existing Key, manually, it much be much faster than loading by new Query

Igor Artamonov
  • 35,450
  • 10
  • 82
  • 113
  • What deeply sucks about `List>` is that I can't automatically match `Organization` class with corresponded `OrganizationProxy` class for RequestFactory. That means I'll have to have **three** (!!) classes per logical entity. One is for using with Objectify, second is serverside POJO and third is clienside proxy for POJO. It sounds pretty bizarre. Do you know if this problem can be solved more elegantly ? Спасибо! – expert Oct 19 '11 at 06:17
  • 1
    Can you use it as 2 fields - `contactPeopleKeys` and `contactPeople`? first is standard stored field, second (that will be filled in PostLoad) for matching only? PS actually I cant fully understand this idea with `OrganizationProxy`. Пожалуйста :) – Igor Artamonov Oct 19 '11 at 06:34
  • I guess I will have to mark `List contactPeople` as @Transient ? Hmm.. Good point. Thanks for the idea. And **[here](http://code.google.com/webtoolkit/doc/latest/DevGuideRequestFactory.html#proxies)** is explanation of proxies in RequestFactory framework. – expert Oct 19 '11 at 06:38
  • My fight with Objectify continues. I can't make nice and cute serialization of children in `PrePersist` handler. Check this out: http://stackoverflow.com/questions/7830421/can-i-persist-child-objects-in-prepersist-handler-of-a-parent-class-objectify – expert Oct 20 '11 at 03:11