Как удалить ассоциацию @ManyToMany (присоединенную ссылку), не удаляя фактическую целевую сущность

1

Я работаю над приложением Spring-MVC, и в нем есть много-много картинок. Существует 3 таблицы, одна из которых - GroupAccount, memberjunction, GroupMembers. Теперь, когда я удаляю groupMember, я хочу только удалить записи из GroupMembers и memberjunction, соответствующие члену. Я попытался использовать Cascade.Remove, он также вызвал удаление в GroupAccount. Я отправляю свой код sql и то, что у меня есть до сих пор.

Код SQL:

CREATE TABLE groupaccount
(
  groupid numeric NOT NULL,
  groupname character varying,
  adminusername character varying,
  CONSTRAINT groupid PRIMARY KEY (groupid)
)
CREATE TABLE memberjunction
(
  memberid integer NOT NULL,
  groupid numeric NOT NULL,
  CONSTRAINT membergroupid PRIMARY KEY (memberid, groupid),
  CONSTRAINT groupaccount_memberjunction_fk FOREIGN KEY (groupid)
      REFERENCES groupaccount (groupid) MATCH SIMPLE
      ON UPDATE NO ACTION ON DELETE NO ACTION,
  CONSTRAINT groupmembers_memberjunction_fk FOREIGN KEY (memberid)
      REFERENCES groupmembers (memberid) MATCH SIMPLE
      ON UPDATE NO ACTION ON DELETE NO ACTION
)
CREATE TABLE groupmembers
(
  memberid integer NOT NULL,
  musername character varying,
  accesslevel boolean DEFAULT true,
  CONSTRAINT memberid PRIMARY KEY (memberid)
)

Метод делегирования GroupMembersDAOImpl:

@Override
public boolean removeGroupMember(int memberId) {
    session = sessionFactory.getCurrentSession();
    GroupMembers groupMembers = (GroupMembers) session.get(GroupMembers.class, memberId);
    if(!(groupMembers == null)){
        groupMembers.getGroupAccounts().clear();
        session.flush();
        session.delete(groupMembers);
        return true;
    } else {
        return false;
    }
}

Объект GroupAccount:

@Entity
@Table(name="groupaccount")
public class GroupAccount {
 @Id
    @Column(name="groupid")
    @GeneratedValue(strategy = GenerationType.SEQUENCE,generator = "groupaccount_seq_gen")
    @SequenceGenerator(name = "groupaccount_seq_gen",sequenceName = "groupaccount_seq")
    private Long groupId;
 @ManyToMany(cascade = CascadeType.ALL)
    @JoinTable(name = "memberjunction", joinColumns = {@JoinColumn(name = "groupid")},
                inverseJoinColumns = {@JoinColumn(name = "memberid")})
    private Set<GroupMembers> groupMembersSet = new HashSet<>();

    public void setGroupMembersSet(Set<GroupMembers> groupMembersSet){
        this.groupMembersSet = groupMembersSet;
    }

    public Set<GroupMembers> getGroupMembersSet(){
        return this.groupMembersSet;
    }
}

GroupMembers Entity:

@Entity
@Table(name="groupmembers")
public class GroupMembers {

 @Id
    @Column(name="memberid")
    @GeneratedValue(strategy = GenerationType.SEQUENCE,generator = "groupmembers_seq_gen")
    @SequenceGenerator(name = "groupmembers_seq_gen",sequenceName = "groupmembers_seq")
    private int memberid;
 @ManyToMany(mappedBy = "groupMembersSet")
    private Set<GroupAccount> groupAccounts = new HashSet<>();

    public void setGroupAccounts(Set<GroupAccount> groupAccounts){
        this.groupAccounts = groupAccounts;
    }

    public Set<GroupAccount> getGroupAccounts(){
        return this.groupAccounts;
    }
}

Последний журнал ошибок:

org.postgresql.util.PSQLException: ERROR: update or delete on table "groupmembers" violates foreign key constraint "groupmembers_memberjunction_fk" on table "memberjunction"
  Detail: Key (memberid)=(2501) is still referenced from table "memberjunction".
    org.postgresql.core.v3.QueryExecutorImpl.receiveErrorResponse(QueryExecutorImpl.java:2198)
    org.postgresql.core.v3.QueryExecutorImpl.processResults(QueryExecutorImpl.java:1927)

Вышеуказанный метод не работает, как говорится, есть ссылка на memberJunction. Как я могу также запросить элемент memberJunction и удалить записи, соответствующие члену. Любая помощь будет приятной. Большое спасибо.. :-)

  • 0
    Вы должны добавить свои карты сущностей тоже.
  • 0
    @VladMihalcea Объекты добавлены ... :-) Пожалуйста, дайте мне знать .. :-)
Теги:
spring
hibernate
jpa
hibernate-mapping

1 ответ

1
Лучший ответ

Вам необходимо сделать следующее:

for(GroupAccount groupAccount : groupMembers.getGroupAccounts()) {
    groupAccount.getGroupMembersSet().remove(this);
}
groupMembers.getGroupAccounts().clear();
session.flush();
session.delete(groupMembers);

Поскольку у вас есть ассоциация @ManyToMany, таблица связей недоступна во время выполнения. Для этого вы можете:

  1. Очистить GroupAccounts от GroupMembers до удаления GroupMembers. убедитесь, что вы сбросили флажок, чтобы убедиться, что действие удаления не препятствует обновлению в состоянии удаляемого объекта.

  2. Вы можете заменить @ManyToMany с @OneToMany ассоциации к MemberJunction лица (чей PK/@Id будет строить из обоих GroupMembers и GroupAccount). Таким образом, вы можете каскадное удаление от GroupMembers к MemberJunction mappedBy Set, потому что он будет удалять строки таблицы ассоциаций, а не фактическое GroupAccount сущность.

  • 0
    Спасибо за вашу помощь. Это не сработало. Я обновляю свой пост обновленным кодом и журналом ошибок. Большое спасибо. :-)
  • 0
    Проверьте мой обновленный ответ. Вы должны установить обе стороны ассоциаций, то есть вы должны удалить удаляемые GroupMembers из экземпляров GroupAccount.
Показать ещё 8 комментариев

Ещё вопросы

Сообщество Overcoder
Наверх
Меню