2011-03-18 96 views
0

我有很多一对多的标签 < - >软件,当我删除标签我想删除这些都与另一这是关系到标签,但不是所有的软件标签。这里的业务逻辑如下:没有标签,软件不能存在。下面有两个类和一个测试的代码。许多一对多级联删除

现在即使它们与其他标签相关,它也会删除所有软件。

如何处理?

@Entity 
public class Tag extends Model { 

    @Column(nullable = false, unique = true) 
    public String title; 

    public Tag(String title) { 
     this.title = title; 
    } 

    @ManyToMany(cascade = CascadeType.ALL, mappedBy = "tags") 
    public List<Software> softwares = new LinkedList<Software>(); 

} 


@Entity 
public class Software extends Model { 

    public String title; 
    public String description; 

    @ManyToOne(optional = false) 
    public Author author; 

    @ManyToMany 
    public List<Tag> tags = new LinkedList<Tag>(); 

    public Software(String title, String description, Author author) { 
     this.title = title; 
     this.description = description; 
     this.author = author; 
    } 


    public Software(String title, String description, Author author, Tag ... tags) { 
     this(title, description, author); 


     if (!Arrays.asList(tags).contains(null)) { 

      // it needed if we wand to delete Tags with cascade - when delete Tag, then delete all Softwares related to it 
      for (Tag tag : tags) { 
       this.tags.add(tag); 
      } 

      for (Tag tag : tags) { 
       tag.softwares.add(this); 
      } 
     } 
    } 

} 

有一个测试:

@Test 
public void testDelete() throws InterruptedException { 

    Tag tag1 = new Tag("tag1").save(); 
    Tag tag2 = new Tag("tag2").save(); 

    Author author1 = new Author("name", "email").save(); 


    new Software("title1", "description1", author1, tag1).save(); 

    new Software("title3", "description3", author1, tag1, tag2).save(); 


    tag1.delete(); 

    // try to find the software 
    assertEquals(1, Software.findAll().size()); // IT FAILS - IT DELETES ALL 
} 
+0

你的问题似乎很混乱。您正在删除标签并在所有软件上声明? – Nilesh 2011-03-18 10:25:14

+0

我只是检查一个(1)软件应该保留,因为它也与tag2有关。所以当我删除标签1 - 软件title1应该被删除,但软件与title3不应该。 – ses 2011-03-18 10:39:07

+0

你可以在tag1.delete()之前声明吗?并看看你会得到什么结果? – Nilesh 2011-03-18 11:19:15

回答

2

触发,或逻辑在你的服务层是实现这一目标的最佳选择。如果你真的想要通过模型,规范化它,在这里你可以选择在删除行为。

1

之后,当不再有任何引用将它加入标记记录时,软件记录被删除,与DELETE_ORPHAN级联类型给出的内容类似,但我认为这不支持@ManyToMany

正如Alexis所指出的那样,您可以通过数据库触发器来实现此目的,但另一种方法可能是使用interceptors or events

+0

是的,它不支持在多对多,不幸的是。我倾向于认为不要依赖级联(除去级联),而是在DAO层执行添加动作,以处理可以被删除的关系。 (我尝试不处理触发器或额外的逻辑ID数据库) – ses 2011-03-18 12:24:28