播放框架2.1和Ebean:@ManyToOne和@OneToMany,CRUD和级联问题

时间:2013-03-16 13:51:37

标签: ebean playframework-2.1

我想知道的是:当我删除类别时,可以删除所有相关文章,当我删除文章时,也可以删除它的相关类别。

我将映射关系设置为@ManyToOne@OneToMany(cascade = CascadeType.ALL, mappedBy = " category"),就像下面的代码一样,但是当我进行单元测试时,会出现几个问题,但它不起作用。 这是我的代码:

@Entity
public class Article extends Model {
    @Id
    public Long id;     

    @Constraints.Required       
    public String title;

    @Constraints.Required
    @Lob
    @Basic(fetch = FetchType.LAZY)
    public String content;

    public boolean published = false;

    @Formats.DateTime(pattern="yyyy-MM-dd")
    public Date publishDate;

    @ManyToMany(cascade = CascadeType.REMOVE)
    @Column(nullable = true)
    public List<Tag> tags = new ArrayList<Tag>();

    @ManyToOne
    @Column(nullable = true)
    public Category category;

    public static Finder<Long, Article> finder = new Finder<Long, Article>(Long.class, Article.class);

    public Article(String title, String content, Tag[] tags) {
        this.title = title;
        this.content = content;
        this.publishDate = new Date();
        this.category = null;
        if(tags != null)
            for(Tag t : tags)
                this.tags.add(t);
    }

    public static List<Article> all() {
        return finder.orderBy("publishDate desc").findList();
    }

    public static Article create(String title, String content, Tag[] tags) {
        Article article = new Article(title, content, tags);
        article.save();
        article.saveManyToManyAssociations("tags");
        return article;
    }

    public static void delete(Long id) {
        finder.ref(id).delete();
    }

    public static void setCategory(Article article, Category c) {
        if(article.category != null)
            Category.removeArticle(c, article);
        article.category = c;   
        Category.addArticle(c, article);
        article.update();
    }
}

这是分类:

@Entity
public class Category extends Model {
    @Id
    public Long id; 

    @Required
    public String name;

    @OneToMany(mappedBy = "category", cascade = CascadeType.ALL)
    Set<Article> articles;

    public static Finder<Long, Category> finder = new Finder<Long, Category>(Long.class, Category.class);

    public Category(String name) {
        this.name = name;
    }

    public static List<Category> all() {
         return finder.all();
    }

    public static Category create(String name) {
        Category category = new Category(name);
        category.articles = new HashSet<Article>();
        category.save();
        return category;
    }

    public static String rename(Long id, String newName) {
        Category category = finder.ref(id);
        category.name = newName;
        category.update();
        return newName;
    }

    public static void delete(Long id) {
        Category c = finder.ref(id);
        c.delete(); 
    }

    public static void addArticle(Category c, Article article) {
        if(! c.articles.contains(article)) {
            article.category = c;
            c.articles.add(article);
            article.update();
        }
    }

    public static void removeArticle(Category c, Article article) {
        if(c.articles.contains(article)) {
            Article.delete(article.id);
            c.articles.remove(article);
        }
    }

    public static Map<String,String> options() {
        LinkedHashMap<String,String> options = new LinkedHashMap<String,String>();
        for(Category c: Category.finder.orderBy("name asc").findList()) {
            options.put(c.id.toString(), c.name);
        }
        return options;
    }
}

这是我的测试:

@Test
public void categoryTest() {
    Category c1 = Category.create("Play");
    Category c2 = Category.create("SSH");
    Category c3 = Category.create("Python");
    Category c4 = Category.create("web");

    String newName = Category.rename(c3.id, "Django");

    Category.delete(c2.id);

    List<Category> list = Category.all();
    assertEquals(3, list.size());

    Map<String, String> map = Category.options();


    Article a1 = Article.create("Hello", "Hello world, My Blog!", null);
    Article a2 = Article.create("My Blog", "It's build by play framework", null);
    Article a3 = Article.create("Play", "Install Play", null);

    Category.addArticle(c1, a1);
    Category.addArticle(c1, a2);
    Category.addArticle(c3, a3);

    Category.delete(c3.id);
    Category.removeArticle(c1, a1);

    assertEquals(2, list.size());
    assertEquals("Play", list.get(0).name);

    //assertEquals("Django", map.get("3"));
    assertEquals(1, Article.all().size());

    assertEquals(1, c1.articles.size());
    assertEquals(false, c1.articles.contains(a1));
}

以下声明无法通过。

assertEquals(2, list.size()); 

这意味着现在可以删除类别,但

Category.delete(c2.id); 

作品!

assertEquals(1, Article.all().size()); 

以上断言无法通过。这意味着类别无法删除它的相关文章。 我该怎么做才能解决这个问题?

1 个答案:

答案 0 :(得分:1)

在上面的代码中,只有一个断言没有通过。这是:

assertEquals(2, list.size()); 

为什么会这样?

让我们看一下以下代码:

List<Category> list = Category.all();
assertEquals(3, list.size());
Category.delete(c3.id);
assertEquals(2, list.size());

在第一行,我们采用所有类别,其中有三个 在第三行,我们删除一个类别。此类别已正确删除,但在第一行计算的类别列表仍有三个元素。这是因为此列表不代表数据库的当前状态。它仍然保存在上面代码的第一行中计算的结果 为了使第二个断言正常工作,我们必须在第3行和第4行之间添加以下行:

list = Category.all();

上面的代码将计算当前的类别列表并将其分配给变量`list&#39;。