Как создать отношения «многие ко многим» с Objectify в Google App Engine? - PullRequest
5 голосов
/ 05 февраля 2012

Я не могу найти документацию по подходящему способу установления связи между многими объектами с помощью Objectify в Google App Engine.

Кто-нибудь может объяснить, как это сделать?Нужно ли для этого создать новый класс "join"?Насколько это будет эффективно?

Ответы [ 4 ]

2 голосов
/ 21 февраля 2013

Я решил использовать этот подход с Objectify 4.0:

@Entity
@Index
public class Module {

@Id
private Long id;
private String name;

@Load
private List<Ref<Template>> templates;


public List<Template> getTemplates() {
    List<Template> templates = new ArrayList<Template>();

    for (Ref<Template> temp : this.templates) {
        templates.add(temp.get());
    }

    return templates;
}

public void setTemplates(List<Template> templatesParm) {
    List<Ref<Template>> templates = new ArrayList<Ref<Template>>();

    for (Template temp : templatesParm) {
        templates.add(Ref.create(temp));
    }

    this.templates = templates;

}
2 голосов
/ 15 мая 2012

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

Class Link{
    Key<?> master;
    key<?> slave;

    public Link(){

    }

    public setLink(Entity master, Entity slave){
     //initialize

    }

}

Затем вы можете создать объект Link для моделирования отношений.Это автоматически сопоставляет отношения «один к одному» или «многие ко многим»

2 голосов
/ 05 февраля 2012

Какие типы запросов вам нужно поддерживать?

Самое простое решение:

@Entity
public class StoredObject {
    @Id
    private Long id;

    private List<Long> relatedIds;
}

, тогда, учитывая StoredObject, вы можете вызвать objectify.get(StoredObject.class, storedObject.getRelatedIds()), чтобы получить всесоответствующие идентификаторы.

Чтобы ускорить некоторые запросы в моем собственном приложении, я создал несколько классов соединения.Расходы приходятся на время записи (вы должны поддерживать объединения), но тогда время чтения - это сканирование по одному индексу с последовательными результатами!

1 голос
/ 19 мая 2012

Давайте на минутку подумаем об одном-многих;если вы хотите, чтобы у объекта A было «много» объектов Bs, есть только два способа сделать это:

  • Путь реляции: сделайте каждую точку B на точке A. Когда у вас естьA0 и хотите, чтобы все B, связанные с ним, просто запрашивают B, которые указывают на данный A0.

  • Способ NoSQL / ObjectStore: у A есть поле, содержащеесписок указателей (ключей) на Bs.Обратите внимание, что этот способ также позволяет B быть в определенном порядке (несмотря на то, что документы GAE / Java наоборот).

Какой из них лучше, зависит.Способ ObjectStore ограничен размером объекта.Реляционный путь подвержен тонкой проблеме в том смысле, что если A и все B не находятся в одной группе сущностей, и вы не выполняете запрос предка в транзакции (или, может быть, даже если он не в транзакции), вы гарантированно получите все из B, которые указывают на это A. Однако, если A и B охватывают группы сущностей, возможно (хотя возможно и маловероятно), что вы получите B, который не удовлетворяет предикату запроса, или пропуститеa B: https://developers.google.com/appengine/articles/transaction_isolation

В (теперь стандартном) хранилище данных с высокой репликацией транзакция обычно полностью применяется в течение нескольких сотен миллисекунд после возврата фиксации.Однако, даже если он не применяется полностью, последующие запросы на чтение, запись и запросы предков всегда будут отражать результаты фиксации, поскольку эти операции применяют любые незавершенные модификации перед выполнением.Однако запросы, которые охватывают несколько групп сущностей, не могут определить, есть ли какие-либо ожидающие изменения перед выполнением, и могут возвращать устаревшие или частично примененные результаты.

Теперь для многих-многих: однажды я прочитал историю, в которой описываетсяв туалет в космосе;было четыре комбинации: внутри / снаружи космического корабля и два вида посещения туалета.Для последней комбинации нахождения вне корабля (в скафандре) и устранения твердых тел единственным ответом было «нет никакого изящного пути» (также заголовок статьи): http://settlement.arc.nasa.gov/CoEvolutionBook/SPACE.HTML#There НеНет изящного пути ... и это также ответ на многие-многие отношения в GAE.Вы можете создать их, используя класс соединения, и каждая сторона соединения может быть реализована с помощью запроса или списка ключей.

...