2013-03-16 7 views
5

Ich möchte feststellen, dass: Wenn ich die Kategorie lösche, können alle zugehörigen Artikel gelöscht werden und wenn ich den Artikel lösche, kann es auch sein gelöscht in seiner verwandten Kategorie.play framework 2.1 und Ebean: @ManyToOne und @OneToMany, CRUD und Kaskadenprobleme

Ich legte die Zuordnung @ManyToOne und @OneToMany(cascade = CascadeType.ALL, mappedBy = " category") nur wie der Code unten, aber wenn ich Unit-Test, mehrere Probleme auftritt, funktioniert es nicht. Dies ist mein Code:

@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(); 
    } 
} 

und das ist die Kategorie Klasse:

@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; 
    } 
} 

Das ist mein Test ist:

@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)); 
} 

Unten assetion nicht passieren können.

assertEquals(2, list.size()); 

Das bedeutet, kann Kategorie‘nun gelöscht werden, aber

Category.delete(c2.id); 

funktioniert!

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

Die oben genannte Überprüfung kann nicht bestanden werden. Das bedeutet, dass die Kategorie zugehörige Artikel nicht löschen kann. Was soll ich tun, um dieses Problem zu lösen?

Antwort

1

Im obigen Code gibt es nur eine Assertion, die nicht besteht. Dies ist:

assertEquals(2, list.size()); 

Warum es passiert?

Blick Lassen Sie uns auf den folgenden Code:

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

In erster Linie nehmen wir alle Kategorien und es gibt drei von ihnen.
In der dritten Zeile löschen wir eine der Kategorien. Diese Kategorie wird ordnungsgemäß gelöscht, aber die Liste der in der ersten Zeile berechneten Kategorien enthält immer noch drei Elemente. Dies liegt daran, dass diese Liste nicht den aktuellen Status der Datenbank darstellt. Es enthält immer noch das Ergebnis, das in der ersten Zeile des obigen Codes berechnet wurde.
Damit zweite Behauptung richtig funktioniert, müssen wir folgende Zeile zwischen Zeile 3 und 4 hinzuzufügen:

Above Code aktuelle Liste der Kategorien berechnen und sie auf Variable `Liste‘ zuweisen.

Verwandte Themen