5

実現したいのは、カテゴリを削除すると、関連するすべての記事が削除され、記事を削除すると、関連するカテゴリでも削除される可能性があることです。

以下のコードのようにマッピング関係を設定した@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()); 

上記資産は通過できません。つまり、カテゴリは関連記事を削除できません。この問題を解決するにはどうすればよいですか?

4

1 に答える 1