2013-03-16 7 views
5

Я хочу понять, что: когда я удаляю категорию, все связанные с ней статьи могут быть удалены, и когда я удалю статью, она также может быть удалены в соответствующей категории.Play framework 2.1 и Ebean: @ManyToOne и @OneToMany, CRUD и проблемы с каскадом

Я установил отношение отображения @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)); 
} 

Ниже assetion не может пройти.

assertEquals(2, list.size()); 

Это означает, что категория может»быть удален теперь, но

Category.delete(c2.id); 

работает!

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

Выше средства не могут проходить. Это означает, что категория не может удалить связанные статьи. Что мне делать для решения этой проблемы?

ответ

1

В приведенном выше коде есть только одно утверждение, которое не проходит. Это:

assertEquals(2, list.size()); 

Почему это происходит?

Давайте посмотрим на следующий код:

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

В первой строке мы берем все категории и есть три из них.
В третьей строке мы удаляем одну из категорий. Эта категория удалена, но список категорий, вычисляемых в первой строке, имеет три элемента. Это связано с тем, что этот список не отражает текущее состояние базы данных. Он по-прежнему содержит результат, вычисленный в первой строке выше кода.
Чтобы сделать второе утверждение работу должным образом, мы должны добавить следующую строку между линией 3 и 4:

Приведенный выше код вычисляет текущий список категорий и назначить его переменной `список».

 Смежные вопросы

  • Нет связанных вопросов^_^