标记< - >我有多对多软件,当我删除标签时,我想删除与该标签相关的所有软件但不是与另一个标签相关的软件。这里的业务逻辑如下:没有标签的软件不能存在。下面有两个类和一个测试的代码。
现在它删除所有软件,即使它们与其他标签相关。
如何处理?
@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 :(得分:2)
服务层中的触发器或逻辑是实现它的最佳选择。如果你真的想通过模型来规范它,那么你可以选择在删除行为上做。
答案 1 :(得分:1)
您所追求的是,当不再有任何引用将其加入标记记录时,软件记录被删除,类似于DELETE_ORPHAN
级联类型给出的,但我不认为这支持@ManyToMany
。
正如Alexis所说,你可以通过数据库触发器实现这一目标,但另一种方法可能是使用interceptors or events。