Невозможно связать сущность, полученную в результате транзакции, с другой сущностью в Objectify

У меня есть некоторые проблемы с отношениями сущностей в Objectify. Мое приложение — это приложение для событий, в котором на события есть билеты разных категорий; каждый билет принадлежит пользователю. У меня есть родительская/дочерняя иерархия, например Event > TicketType > Ticket. Итак, Event — это @Parent TicketType, который является @Parent of Ticket.

Вот мои сущности:

@Entity
public class Event {
    ...
    @Load
    private Set<Ref<TicketType>> ticketTypes = new HashSet<Ref<TicketType>>();
    ...
}

@Entity
public class TicketType {
    ...
    @Parent
    private Ref<Event> event;
    ...
}

@Entity
public class Ticket {
    ...
    @Parent
    @Load
    private Ref<TicketType> ticketType;
    ...
}

Я создаю событие внутри транзакции следующим образом:

Event ev = ofy().transact(new Work<Event>() {

    @Override
    public Event run() {
    // several statements constructing the event
        ev.setXXXX(X);
    ofy().save().entity(ev).now();
        // Now construct the TicketType entity, then associate it to its parent, Event
    TicketType tt1 = new TicketType("normal", 100, 7);
    tt1.setEvent(ev);
        ofy().save().entity(tt1).now();
        return ev;
    }

});

Используя возвращенный ev, я создаю билеты следующим образом:

// Generate a VIP ticket
Ticket ticket1 = ev.generateTicket("vip");
// I set the owner with an already saved User entity
ticket1.setOwner(cl);
ofy().save().entity(ticket1).now();
// The user also has a list of all his tickets
cl.addTicket(ticket1);

Внутри Event.generateTicket(...) я делаю:

public synchronized Ticket generateTicket(String type) throws IllegalArgumentException {
    for (Ref<TicketType> reftt : ticketTypes) {
        TicketType tt = reftt.get();
        if (tt.getType().equalsIgnoreCase(type)) {
            if (tt.getAvailable() > 0) {
                Ticket newTicket = new Ticket(RandomGenerator.nextNumber(TICKET_NUMBER_LENGTH), tt);
                newTicket.setExpirationDate(getEndDate());
                // here I set the parent TicketType entity for this new Ticket
                newTicket.setTicketType(tt);
                // the number of available tickets of this type is decreased
                tt.setAvailable(tt.getAvailable() - 1);
                return newTicket;
            } else return null;
        }
    }
    throw new IllegalArgumentException("No such type");
}

Моя проблема заключается в том, что отношение родитель/потомок, по-видимому, соблюдается только в объекте Event, который правильно имеет список всех типов событий/билетов (через поле ticketTypes, которое является Set<Ref<TicketType>>. Но объект TicketType не имеет списка ticket (поле tickets пустое, поэтому не сохраняется), и в другом направлении родительская ссылка TicketType в Ticket равна null, так же как и родительская ссылка Event в TicketType, несмотря на назначения, которые я сделал в обоих случаях выше.

Что я делаю неправильно?


person sbruno74    schedule 08.01.2013    source источник


Ответы (1)


Я не думаю, что вы делаете что-то неправильно здесь. Однако я считаю, что Objectify не будет автоматически загружать отношения «один ко многим». Правильный способ получить все типы билетов — сначала загрузить объект Event, а затем выполнить запрос предка для типа билета.

Небольшой совет: похоже, вы проектируете свои сущности так же, как вы проектируете таблицы в реляционной базе данных. Такие концепции не применяются к хранилищу данных. Как указано во введении к объектизации, вы должны представить себе хранилище данных как хэш-карту хэш-карты. Было бы целесообразно использовать многозначный атрибут, который содержит значения перечисления для типа билета в объекте билета. Меньше сущностей — это всегда хорошо в хранилище данных.

person konqi    schedule 09.01.2013
comment
Спасибо за ваш ответ. Я видел в документации, что аннотация @Load также работает с набором сущностей, что означает, что типы заявок должны загружаться с сущностью Event. Я неправильно понимаю? Кроме того, причина, по которой я создал TicketType как объект, заключается в том, что тип билета имеет множество атрибутов и может иметь связанные с ним поведения (сколько доступно?, цена, политика скидок и т. д.). Можете ли вы привести конкретный пример кода? - person sbruno74; 10.01.2013