objectify / google app引擎中的外键

时间:2014-05-04 15:18:34

标签: java google-app-engine objectify

我正在尝试使用Objectify为谷歌应用引擎编写应用程序,但我遇到了一些麻烦。我是noSQL数据存储的新手,所以这可能是一个概念问题。

我有一个称为消息的实体,每条消息都有一个来自用户 - 创建消息的用户。

@Entity
public class Message {


@Index private Key<User> fromUserKey;
@IgnoreSave private  User fromUser;

令人讨厌的是,我必须在邮件中同时拥有User和Key字段。 JSON需要User对象使用有用字段填充响应,并且Google App引擎需要Key才能将引用存储到用户。 @IgnoreSave注释用于阻止Objectify要求谷歌应用引擎尝试存储用户对象(这将失败)。

获取邮件时,将填充from用户密钥,但不会填充from User对象。以下是我的“getMessages”操作的DAO代码:

    public static List<Message> getSentMessages(long userId) {
    List<Message> result;
    result= ofy().load().type(Message.class).filter("from", Key.create(User.class, userId)).limit(1000).list();
    return result;
}

但是每个Message上都没有填充fromUser对象,只有fromUserKey。如何获取响应中填充的实际用户对象?我需要访问forename,surname等字段 - 而不仅仅是用户的ID。我可以从数据库中获取用户,循环结果,然后在每条消息上调用setFromUSer,但这很难看。它还会导致ConcurrentModificationException ...

我确定我在这里做错了什么,但我无法解决问题。

1 个答案:

答案 0 :(得分:1)

您可以做的是在Ref<User>实体上拥有属性Message并使用'@Parent'进行注释。这意味着每个Message实体将成为用户实体组的一部分。 Ref<?>的作用类似于键,但允许您直接访问实际的实体对象;通过这种方式,您可以轻松获得姓氏,姓氏等。

按如下方式更改课程:

@Entity
@Cache
public class Message
{
    @Id Long id;
    @Load @Parent private Ref<User> user;

    public User getUser() { return this.user.get(); }
    public void setUser(User value) { this.user = Ref.Create(value); }
}

完成后,您将能够执行祖先查询以检索与特定用户关联的所有消息实体:

public static List<Message> getSentMessages(long userId) 
{
    User parent = ofy().load().type(User.class).id(userId).now();
    List<Message> results = ofy().load().type(Message.class).ancestor(parent).limit(1000).list();   
    return results;
}

您现在应该能够做您想做的事情,并希望不会再犯错误。