我想知道的是:当我删除类别时,可以删除所有相关文章,当我删除文章时,也可以删除它的相关类别。
我将映射关系设置为@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());
以上断言无法通过。这意味着类别无法删除它的相关文章。 我该怎么做才能解决这个问题?
答案 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;。