каскадное удаление многие ко многим - PullRequest
0 голосов
/ 18 марта 2011

У меня есть многие ко многим для тега <-> программного обеспечения , когда я удаляю тег, я хочу удалить все программы, связанные с этим тегом, НО, которые не связаны с другой тег. Бизнес-логика здесь следующая: Программное обеспечение не может существовать без тега . Ниже приведен код с двумя классами и одним тестом.

Теперь он удаляет все программы, даже если они связаны с другими тегами.

Как с этим справиться?

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

Ответы [ 2 ]

2 голосов
/ 18 марта 2011

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

1 голос
/ 18 марта 2011

То, что вам нужно, что запись программного обеспечения удаляется, когда больше нет ссылок, присоединяющих ее к записи тега, похоже на то, что задается каскадным типом DELETE_ORPHAN, но я не думаю, что это поддерживается для @ManyToMany.

Как отмечает Алексис, этого можно добиться с помощью триггеров базы данных, но другой подход может заключаться в использовании перехватчиков или событий .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...