Удалить строку только в таблицу соединений - PullRequest
0 голосов
/ 17 февраля 2019

Вопрос

Можно ли удалить строку в объединяющей таблице, созданной аннотацией @ManyToMany?

Context

С этой схемой:

  • TAG
  • TAGS_ARTICLES
  • ARTICLE

Когда тег удаляется из public Set<Tag> tags (aсписок в ARTICLE классе) также удаляются соответствующие строки в TAGS_ARTICLES, но не тег в таблице TAG.

Единственный способ - создать сценарий SQL или JPA / Hibernate, позволяющий нам сделатьчто с аннотациями?

Код

Мой текущий код: article.getTags().remove(tag);

Эта строка удаляет тег из списка, но изменениене сделано в базе данных.

Заключение

Я видел этот пост: Как удалить строку в объединяемой таблице с JPA , но относительный тег долженбыть удаленным тоже (не мой случай).

Спасибо.

Редактировать 1: Ожидаемый результат в базе данных

До удаления

ARTICLE

| article_id |
| a1         |
| a2         |
| a3         |

TAGS_ARTICLES

| article_id | tag_id |
| a1         | t1     |
| a1         | t2     |
| a2         | t2     |

TAG

| article_id |
| t1         |
| t2         |

После удаления t1 из списка тегов a1

ARTICLE

| article_id |
| a1         |
| a2         |
| a3         |

TAGS_ARTICLES

| article_id | tag_id |
| a2         | t1     |
| a2         | t2     |

TAG

| article_id |
| t1         |
| t2         |

Редактировать 2: Присоединить код таблицы

@Entity
public class Article {
     ...
     @ManyToMany
     @JoinTable(name = "tags_articles",
        joinColumns = @JoinColumn(name = "idarticle"),
        inverseJoinColumns = @JoinColumn(name = "idtag")
     )
     private Set<Tag> tags = new HashSet<>();
     ...
}

Ответы [ 2 ]

0 голосов
/ 17 февраля 2019

Поведение операции объекта зависит от принадлежности отношения, которое определяется тем, куда вы помещаете атрибут mappedBy в аннотацию.Субъект, имеющий mappedBy, является тем, кто не является владельцем.Обе стороны отношений не могут быть владельцами.

Здесь нужно определиться с правильным владельцем.Допустим, тег является владельцем.Тогда при удалении тега отношение TAGS_ARTICLES будет обновлено автоматически.при удалении TAGS_ARTICLES вы должны позаботиться об удалении отношения самостоятельно.

@Entity
public class Tag{
    @ManyToMany
    Set<Tag_Articles> articles;
    //...
}

@Entity
public class Tag_Articles{
    @ManyToMany(mappedBy="articles")
    Set<Tag> tags;
    //...
}

Для описанных выше отношений сущностей вы можете попробовать что-то вроде этого -

entityManager.remove(articles)
for (Tag tag: articles.tags) {
     tag.articiles.remove(articles);
}
0 голосов
/ 17 февраля 2019

Редактировать: см. Комментарии

Использование этой настройки должно привести к желаемому результату

class Article {
   ...  

   @ManyToMany
   @JoinTable(...)
   private Set<Tag> tags = new HashSet<>();
}

class Tag {
   ...

   @ManyToMany(mappedBy = "tags")
   private Set<Article> articles = new HashSet<>();
}

Субъект Article вступает во владение отношениями.


Старый ответ .

При удалении тега из public Set<Tag> tags (список в классе ARTICLE) тоже удаляется соответствующая строка в TAGS_ARTICLES, но не тегв таблицу TAG.

Под этим я понимаю, что осиротевшие записи не удаляются.И вы хотите удалить их.Это правильно?

Возможно, вы захотите попробовать использовать специфическую для Hibernate аннотацию @Cascade ( документация ).
Просто аннотируйте свое поле Collection<T>.

@ManyToMany(...)
@Cascade(CascadeType.REMOVE) // or CascadeType.DELETE
private Set<Tag> tags = new HashSet<>();

Не забудьте включить его из пакета org.hibernate.annotations.

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