1

作为一名 Java 开发人员,我刚开始使用 Play Framework 2.1.1。

从现有数据库中获取了一些 eBean,我正在构建一个 RESTful 架构来服务和保存来自 RESTful 客户端 Web 应用程序的这些 bean。

我有以下 bean 定义。Feed 是应用程序的核心对象。为简单起见,我没有包括 getter 和 setter 以及许多其他 bean,我专注于给我带来麻烦的那些:

@Entity
public class Feed extends Model implements Serializable
{
    @Id
    Long feedId;
    ...
    ...
    ...
    @JsonManagedReference("feed-item")
    @OneToMany(fetch = FetchType.LAZY, mappedBy = "feed")
    List<Item> items;
    @JsonManagedReference("feed-userFeed")
    @OneToMany(fetch = FetchType.LAZY, mappedBy = "feed")
    List<UserFeed> userFeeds;
}

@Entity
public class Item extends Model implements Serializable
{
    @Id
    Long itemId;
    ...
    ...
    ...
    Long urlId;
    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "url_id")
    Url url;
    @Formats.DateTime(pattern = "yyyy-MM-ddThh:mm:ss")
    Timestamp itemPublishedAt;
    @Formats.DateTime(pattern = "yyyy-MM-ddThh:mm:ss")
    Timestamp itemUpdatedAt;
    @Formats.DateTime(pattern = "yyyy-MM-ddThh:mm:ss")
    Timestamp createdAt;
    @Version
    Timestamp updatedAt;
    Long feedId;
    @ManyToOne(fetch = FetchType.LAZY)
    @JsonBackReference("item-feed")
    @JoinColumn(name = "feed_id")
    Feed feed;
    Long urlId;
    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "url_id")
    Url url;
    @OneToMany(fetch = FetchType.LAZY, mappedBy = "item")
    @JsonManagedReference("item-unseen")
    List<Unseen> unseen;
    @OneToMany(fetch = FetchType.LAZY, mappedBy = "item")
    @JsonManagedReference("item-score")
    List<Score> scores;
}

@Entity
public class User extends Model implements Serializable
{
    @Id
    Long userId;
    ...
    ...
    ...
    @OneToMany
    @JsonManagedReference("user-userFeed")
    List<UserFeed> userFeeds;
    @OneToMany
    @JsonManagedReference("user-userTag")
    List<UserTag> userTags;
    @OneToMany
    @JsonManagedReference("user-unseen")
    List<Unseen> unseen;
    @OneToMany
    @JsonManagedReference("user-score")
    List<Score> scores;
}

@Entity
public class Score extends Model implements Serializable
{
    @Id
    Long scoreId;
    ...
    ...
    ...
    Long itemId;
    @ManyToOne(fetch=FetchType.LAZY)
    @JsonBackReference("score-item")
    @JoinColumn(name = "item_id")
    Item item;
    Long userId;
    @ManyToOne(fetch=FetchType.LAZY)
    @JsonBackReference("score-user")
    @JoinColumn(name = "user_id")
    User user;
}

这是我的饲料控制器:

import me.zenfeed.model.Feed;

import org.codehaus.jackson.JsonNode;

import play.db.ebean.Model;
import play.libs.Json;
import play.mvc.BodyParser;
import play.mvc.Controller;
import play.mvc.Result;

public class FeedController extends Controller
{
    public static Result delete(Long id)
    {
        new Model.Finder<>(Long.class, Feed.class).byId(id).delete();
        return ok();
    }

    /* return a JSON with all of the objects found*/
    public static Result get()
    {
        return ok(Json.toJson(new Model.Finder<>(Long.class, Feed.class).fetch("userFeeds", new FetchConfig().query()).where().eq("userFeeds.userId", Long.parseLong(session("connectedUserId"))).findList()));
    }

    /* accept a JSON with the object to save and return a JSON with the new object*/
    @BodyParser.Of(BodyParser.Json.class)
    public static Result post()
    {
        JsonNode json = request().body().asJson();
        Feed f = Json.fromJson(json, Feed.class);
        f.save();
        return ok(Json.toJson(f));
    }

    /* accept a JSON with the object to save and return a JSON with the new object*/
    @BodyParser.Of(BodyParser.Json.class)
    public static Result put(Long id)
    {
        JsonNode json = request().body().asJson();
        Feed f = Json.fromJson(json, Feed.class);
        f.update(id);
        return ok(Json.toJson(f));
    }
}

这是我用来使用一些参数对数据库进行查询的自定义函数:

List<Item> l = new Model.Finder<>(Long.class, Item.class)
.select("itemId, feedId, urlId, title, description, content, author, categories, itemPublishedAt, itemUpdatedAt, wordCount, fresh, vector, createdAt, updatedAt")
.fetch("unseen", "itemId", new FetchConfig().query())
.fetch("scores", "score", new FetchConfig().query())
.fetch("feed.userFeeds", "userId", new FetchConfig().query())
.where()
.eq("feed.userFeeds.userId", Long.parseLong(session("connectedUserId")))
.eq("feed.feedId", feedId)
.orderBy("scores.score")
.findList();

我有几个问题需要帮助:

- 当我尝试调用此控制器的方法 post() 的 POST 请求时,出现以下异常: [RuntimeException: org.codehaus.jackson.map.JsonMappingException: Can not handle managed/back reference 'user-score': no从类型 [collection type; 找到的反向引用属性;class java.util.List, contains [simple type, class me.zenfeed.model.Score]]] 我想我正确地将后向引用放在 Score 模型中,但我不明白......我的 ebeans 是否正确?我的控制器有问题吗?可以做得更好吗?

我现在明白我看到了错误的教程。@JsonManagedReference 和 @JsonBackReference 的参数必须相同。所以对于 feed-item 关系,正确的注释是 @JsonManagedReference("feed-item") 和 @JsonBackReference("feed-item")。

  • 如您所见,我尝试使用类似 HTML5 的格式来格式化 Timestamp 对象,但没有成功。我总是得到长号。我应该转换为 Date 对象吗?如果是的话在哪里?
- 当我使用自定义函数运行查询时,我得到了填充的 URL 对象,即使我明确地将它从我的选择语句中排除(我只想要 URL_ID,而不是整个对象)。

我采用手动方式为我关心的属性生成 HashMap,并将其提供给 Json.toJson() 方法。

谢谢您的帮助。

4

0 回答 0