【问题标题】:Spring, PostgreSQL : Intermediate table for many-to-many entries were automatically deletedSpring,PostgreSQL:自动删除多对多条目的中间表
【发布时间】:2015-06-13 02:58:06
【问题描述】:
  • 我正在开发我正在使用的 Spring-MVC 应用程序 PostgreSQL 作为数据库,Hibernate 作为 ORM 工具。在里面 应用程序我有两个数据库之间的多对多映射 表(GroupAccount,GroupMembers)
    • 昨天发生了一件奇怪的事情,中间 table(MemberJunction) 链接这两个表,条目是 仅针对单个 GroupAccount 删除。当我检查 groupAccount,它在那里,成员也在那里,但是因为 没有条目,没有链接来检索用户 匹配来自 memberJunction 的 groupAccountId。
    • 生产运行debian Wheezy,我找不到 postgresql 登录 /var/logs/ 目录,所以我真的不知道如何 来追踪这个问题。有没有人遇到过类似的问题?作为 从春天开始,我什至不发出可以直接影响的查询 中间表。我正在发布我的 SQL 代码,并且是唯一的一个 例如,当我使用内部联接进行查询时。你能帮忙的话,我会很高兴 因为这发生在生产服务器上。

SQL 代码:

CREATE TABLE groupaccount
(
  groupid numeric NOT NULL,
  groupname character varying,
  adminusername character varying,
  CONSTRAINT groupid PRIMARY KEY (groupid)
)
WITH (
  OIDS=FALSE
);
ALTER TABLE groupaccount
  OWNER TO postgres;

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
)
WITH (
  OIDS=FALSE
);
ALTER TABLE memberjunction
  OWNER TO postgres;

CREATE TABLE groupmembers
(
  memberid integer NOT NULL,
  musername character varying,
  memberaccountstatus boolean NOT NULL DEFAULT false,
  memberactivated boolean NOT NULL DEFAULT false,
  groupaccid numeric NOT NULL DEFAULT 0,
  accesslevel boolean NOT NULL DEFAULT true,
  sortorder numeric NOT NULL DEFAULT 0,
  notedeletenotify boolean NOT NULL DEFAULT false,
  notecreatenotify boolean NOT NULL DEFAULT false,
  canvascreatenotify boolean NOT NULL DEFAULT false,
  attachmentactionnotify boolean NOT NULL DEFAULT false,
  accounteditnotify boolean NOT NULL DEFAULT false,
  notecount integer DEFAULT 0,
  CONSTRAINT memberid PRIMARY KEY (memberid)
)
WITH (
  OIDS=FALSE
);
ALTER TABLE groupmembers
  OWNER TO postgres;

检索成员的 Java 代码:

  @Override
    public List<GroupAccount> returnMemberIdWithMatchingUsername(String memberUsername) {
        session = sessionFactory.getCurrentSession();
        org.hibernate.Query query = session.createQuery("Select ga From GroupAccount as " +
                "ga INNER JOIN ga.groupMembersSet as gm where gm.memberUsername=:memberUsername");
        query.setParameter("memberUsername",memberUsername);
        List<GroupAccount> groupAccountsList = query.list();
  // Other code ommited.
}

GroupAccountModel:

@Entity
@Table(name="groupaccount")
public class  GroupAccount {

 @ManyToMany(fetch = FetchType.LAZY,cascade = CascadeType.REMOVE)
    @JoinTable(name = "memberjunction", joinColumns = {@JoinColumn(name = "groupid")},
                inverseJoinColumns = {@JoinColumn(name = "memberid")})
    private Set<GroupMembers> groupMembersSet = new HashSet<>();
}

GroupMembersModel:

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

    @ManyToMany(mappedBy = "groupMembersSet",fetch = FetchType.LAZY)
    private Set<GroupAccount> groupAccounts = new HashSet<>();

}

因此,这样,当 groupMember 被删除时,groupAccount 不会被删除,而当 groupAccount 被删除时,后续成员也会被删除。

删除组成员:

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

知道可能出了什么问题,或者我如何追踪问题。非常感谢.. :-)

【问题讨论】:

  • 你的映射中有级联删除吗?您是否编辑(删除)了一个项目?
  • @JEY 我在 GroupAccount 而不是 GroupAccount 中进行了级联删除,因为要求是在删除 groupAccount 时删除条目,但未删除或编辑 GroupAccount。对此持积极态度。此外,groupAccount 和 GroupMembers 中存在条目,但 MemberJunction 中不存在。
  • 我在 GroupAccount 中而不是在 GroupAccount 中进行了级联删除???你什么意思?
  • @JEY :我在主帖中添加了一些模型代码,请您检查一下。非常感谢。 :-)

标签: java database spring hibernate postgresql


【解决方案1】:

当您更新 GroupAccount 时使用此映射,特别是当您从 GroupAccount 的 Set groupMembersSet 中删除项目并保存它时;删除了已编辑的 GroupAccount 和 GroupMember 之间的链接,因此删除了表 memberjunction 中的条目。但是,两端的条目都不会被删除。因此,如果您在 groupMembersSet 上执行 clear() 并保存,所有链接都会被删除。

【讨论】:

  • 我不会在任何时候从 GroupAccount 调用 clear(),它只会在删除 groupMember 以删除关联时调用。老实说,我不明白我应该怎么做才能避免这个问题。我正在将我的 removeMember 代码粘贴到主帖中,请查看。
猜你喜欢
  • 1970-01-01
  • 2016-11-12
  • 1970-01-01
  • 1970-01-01
  • 2021-05-10
  • 2016-02-15
  • 2020-06-05
  • 2015-10-24
  • 1970-01-01
相关资源
最近更新 更多