我在Objectify中遇到了与实体关系有关的问题。我的应用程序是一个事件应用程序,其中事件包含不同类别的票每张票都由用户拥有。我有一个父/子层次结构,如Event> TicketType>票。因此,Event是@Parent of TicketType,它是Ticket的@Parent。
以下是我的实体:
@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
字段,即{{1}但是,Set<Ref<TicketType>>
实体没有票证列表(TicketType
字段为空,因此未保存),而在另一个方向上,tickets
父参考在TicketType
中,Ticket
中的Event
父引用也是空的,尽管我在上述两种情况下都进行了分配。
我做错了什么?
答案 0 :(得分:0)
我认为你在这里做错了什么。但我相信Objectify不会自动加载一对多关系。获取所有故障单类型的正确方法是首先加载Event实体,然后对故障单类型执行祖先查询。
一些建议: 看起来您正在设计实体,就像在关系数据库中设计表一样。此类概念不适用于数据存储区。如客观介绍中所述,您应该将数据存储区想象为散列映射的散列映射。我可以使用多值属性,该属性包含票证实体中票证类型的枚举值。在数据存储区中,较少的实体始终是一件好事。