Каков подходящий способ создания объектов с отношением «один ко многим» с использованием Objectify и RequestFactory?

Каков подходящий способ создания объектов с отношением «один ко многим» с использованием Objectify и RequestFactory? Я прочитал документацию по этим библиотекам, а также просмотрел ряд примеров проектов, таких как listwidget и gwtgae2011. Все они используют аннотацию @Embedded, а это не то, что мне нужно, потому что она хранит все в одном объекте. Согласно документации, другим вариантом является использование свойства @Parent в дочерних классах. В моем примере (геттеры/сеттеры удалены для простоты) у меня есть сущности Person и Organization, которые определены как

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

и

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

Теперь, если я правильно понял документацию, чтобы сохранить организацию с одним человеком, я должен сначала сохранить организацию, затем установить organizationKey в ObjectifyService.factory().getKey(organization) для объекта человека, а затем сохранить его. Мне уже не нравится, что мне приходится перебирать каждый дочерний объект вручную, но использование RequestFactory делает все более запутанным из-за наличия прокси-классов. Как бы я определил классы Organization и OrganizationProxy - с Key‹> или без него? Должен ли я определить что-то подобное в 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;
}

И как мне загрузить организацию с ее дочерними элементами из хранилища данных? Придется ли мне вручную извлекать каждого человека и заполнять Organization.contactPeople в методе @PostLoad?

Похоже, мне придется написать МНОГО кода обслуживания только для того, чтобы делать то, что JPA/JDO делает за кулисами. Я просто не понимаю :(

Я что-то упустил или это единственный способ реализовать это?

Заранее большое спасибо за ответы!!!


person expert    schedule 19.10.2011    source источник
comment
После еще большего поиска в Google и чтения кажется, что мне приходится делать все вручную. Кроме того, рассмотрение ограничения отношения родитель-потомок в хранилище данных Google, которое заключается в невозможности повторного использования дочернего элемента с несколькими родителями, приводит меня к выводу, что все мои объекты должны быть корневыми объектами в терминологии хранилища данных. Это наводит меня на другую мысль, что, возможно, мне следует попробовать Twig.   -  person expert    schedule 19.10.2011


Ответы (1)


Вам нужно сделать его как @Parent только тогда, когда вы собираетесь использовать его в транзакции против всех Person в этом Organization. Я уверен, что это не то, что вы хотите.

Достаточно сохранить только private Key<Organization> organizationKey, и фильтровать по этому полю, когда нужно найти Person для заданного Organization

Насчет загрузки всех ссылочных объектов - да, приходится загружать вручную. Это лаваш, но кода не так много.

Также есть другой способ хранения этой связи, если ваша организация достаточно мала и состоит из нескольких сотен человек. В этом случае вы можете иметь List<Key<Person>> contactPeopleKey; и загружать всех этих людей существующими Key вручную, это намного быстрее, чем загрузка новым запросом.

person Igor Artamonov    schedule 19.10.2011
comment
Что глубоко отстойно в List<Key<Person>>, так это то, что я не могу автоматически сопоставить класс Organization с соответствующим классом OrganizationProxy для RequestFactory. Это означает, что мне придется иметь три (!!) класса для каждого логического объекта. Один предназначен для использования с Objectify, второй — серверный POJO, а третий — клиентский прокси для POJO. Звучит довольно странно. Вы не знаете, можно ли решить эту проблему более элегантно? Спасибо! - person expert; 19.10.2011
comment
Можно ли использовать его как 2 поля - contactPeopleKeys и contactPeople? первое - это стандартное хранимое поле, второе (которое будет заполнено в PostLoad) только для сопоставления? PS на самом деле я не могу полностью понять эту идею с OrganizationProxy. Пожалуйста :) - person Igor Artamonov; 19.10.2011
comment
Думаю, мне придется пометить List<Person> contactPeople как @Transient ? Хм.. Хорошее замечание. Спасибо за идею. И здесь объяснение прокси в фреймворке RequestFactory. - person expert; 19.10.2011
comment
Моя борьба с Objectify продолжается. Я не могу сделать красивую и симпатичную сериализацию детей в обработчике PrePersist. Проверьте это: stackoverflow.com/questions/7830421/ - person expert; 20.10.2011