0

我一直在为一个问题苦苦挣扎,我想我只是还不完全了解 GAE Datastore 是如何工作的。

我有以下实体(我删除了问题不需要的代码)

 @Entity
public class Post{

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long Id;

//info
private String title;

//comments
@OneToMany(fetch = FetchType.LAZY,mappedBy = "post")
private List<Comment> comments;

//getter and setters...
}

以及以下实体:

@Entity
public class Comment {

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Key key;

@ManyToOne(fetch = FetchType.LAZY)
private Vibe vibe; // vibe id

//getters and setters...
}

到目前为止一切都很好..我正在使用端点,并且我已经有几个可以正常工作的功能,如果我想添加新帖子或在帖子上发布新评论,我只有在我想获取列表时才会遇到问题特定帖子的所有评论 - 如访问 Post.getComments();

我正在使用 fetch = FetchType.LAZY 因为在某些情况下,我只想获取我的数据库中的所有帖子而没有评论,例如在某种索引中显示它们。

例如,当我尝试这个时:

@ApiMethod(name = "getPostComments")
public List<Comment> getPostComments(@Named("postId") Long postId) {
    EntityManager mgr = getEntityManager();
    List<Comment> results = new ArrayList<Comment>();
    try {
        Post p = mgr.find(Post.class, postId);
        if (p == null) {

            throw new EntityNotFoundException("Post does not exist");

        } else {

            results = p.getComments();
        }

    } finally {
        mgr.close();
    }

    return results;
}

java.lang.IllegalArgumentException 我收到错误的请求错误 400

我尝试了各种不同的方法,但没有运气,我发现的所有解决方案都说我应该使用 fetch = FetchType.EAGER,这是我不想要的,老实说,它看起来好像 LAZY 类型没用。所以很明显我错过了一些东西!请帮忙!如果您可以编写一个获取列表的示例,那就太好了!

4

1 回答 1

0

最终我的解决方案是创建一种新类型的对象,它没有对延迟加载的内部对象的任何引用,并将所需的信息复制到它,然后返回它。

对于这个例子,我这​​样做了:新的 CommentResults 类:

public class CommentResults{

private String message;

private Long userId;

//getters and setters...
}

我的新 getComments 方法如下所示:

@ApiMethod(name = "getPostComments")
public List<CommentResults> getPostComments(@Named("postId") Long postId) {
EntityManager mgr = getEntityManager();
List<CommentResults> results = new ArrayList<Comment>();
try {
    Post p = mgr.find(Post.class, postId);
    if (p == null) {

        throw new EntityNotFoundException("Post does not exist");

    } else {
        for(Comment c:p.getComments()){    //copying the data
            CommentResults cr = new CommentResults();
            cr.setMessage(c.getMessage);
            cr.setUserId(c.getUserId);
            results.add(cr);
        }
    }

} finally {
    mgr.close();
}

return results;
}

我仍然不确定这是否是最好的解决方案,必须创建一个新对象并在每个请求上复制信息对于一个服务器请求来说似乎是一项艰巨的任务,但它现在有效,如果您知道更优雅的解决方案,请分享!

于 2013-10-10T08:08:20.820 回答