ManyToMany 关联删除连接表条目

问题描述 投票:0回答:1

我使用这两个实体创建一个新用户和它关联的组:

@Entity  
@Table(name="usertable")  
@SuppressWarnings("serial")  
@Searchable  
public class User implements Serializable {  

    @GeneratedValue(generator="userIdSeq")  
    @SequenceGenerator(name="userIdSeq", sequenceName="usertable_id_seq")      
    @SearchableId  
    @Id  
    int id;  

    @SearchableProperty  
    String userId;                      // 'Unique identifier. It is formed using this fashion: ''prefix:identifier''  
    String userName;                    // Name used to log in the application.  
    String email;                       // User's email  

    @ManyToMany  
    @JoinTable( name="usergroup",  
                joinColumns=@JoinColumn(name = "userid", referencedColumnName="userId"),  
                inverseJoinColumns=@JoinColumn(name = "groupid")  
    )  
    List<Group> groups;  

    ...  
}  

// Group  
@Entity  
@Table(name="grouptable")  
public class Group implements Serializable {  
    @Id  
    String groupId                  // Unique identifier for group.  
    String description              // Brief text describing the group purposes.  

    @ManyToMany(mappedBy="groups")  
    @Cascade(SAVE_UPDATE)  
    List<User> users  

    ....  
}  

在数据库上: 用户表(ID,用户ID,名称) 组表(id,描述) 用户组(用户 ID、组 ID、组密钥)

将 Group 添加到组列表,调用 User 的 save 方法并观看 hibernate 一起保存 usergoup 是非常令人满意的。但是,当我在保存(用户)操作后检索用户时,hibernate 会自动从用户组表中自动删除条目,这是一个很大的问题。

这里是生成删除用户组的测试序列

  1. 保存新用户
  2. 保存新群组
  3. 并在用户列表中分组
  4. 保存用户
  5. 从电子邮件中获取用户
 @测试
    @事务性
    public void testGetUserByEmail(){
        会话 session = factory.getCurrentSession();

        字符串电子邮件 = “[email protected]”;
        用户 user = createUser();
        user.setWeCanContact(真);
        user.setPartnersCanContact(false);
        user.setAgreedTerms(false);
        user.setReferer("劳拉");

        字符串 groupId = "AARP";
        String description = "Appletalk 地址解析协议";
        组 group1 = new Group();
        group1.setGroupId(groupId);
        group1.setDescription(描述);
        session.save(group1);
        会话.flush();
        user.getGroupLists().add(group1);
        session.saveOrUpdate(用户);

        用户 testUser = userRepository.getUserByEmail(email);
        assertNotNull(测试用户);
        assertEquals("这不是正确的电子邮件", email, testUser.getEmail());
    }
    private User createUser(){
        Session session = factory.getCurrentSession(); 
        String userId = "UB:2010"; 
        String userPassword = "sarah"; 
        String realName = "Sarah Silverman"; 
        String email = "[email protected]"; 

        User user = new User();
        user.setUserId(userId); 
        user.setUserName(email); 
        user.setUserPassword(userPassword); 
        user.setRealName(realName); 
        user.setEmail(email); 

        List<Group> emptyGroupLists = new ArrayList<Group>(); 
        user.setGroupLists(emptyGroupLists); 
        Group group = new Group(); 
        group.setGroupId("ABC"); 
        group.setDescription("A for apple");
        user.getGroupLists().add(group);
        session.save(group); 
        session.save(user); 

        session.flush();
        return user; 
    }
// 从电子邮件中获取用户的存储库方法
//
// @NamedQuery(name="user.findByEmail",
// query="SELECT u FROM User u " +
// "LEFT JOIN FETCH u.groupLists " +
//“哪里上(u.email)=:电子邮件”)

公共用户 getUserByEmail(字符串电子邮件){
    会话 session = sessionFactory.getCurrentSession();
    查询 query = session.getNamedQuery("user.findByEmail");
    query.setParameter("email", email.toUpperCase());
    用户 user = (User)query.uniqueResult();
    返回用户;
}

在执行第 5 步之前,自动删除用户组 like // SQL 输出

Hibernate:
delete
from
usergroup
where
userid=? 

我要注意的几件事; 1. userid 不是用户对象的 pk。那会是问题吗? 2.usergroup中的manyTomany映射由userid和groupid映射 3. 它不仅发生在测试中。它也在开发中。

如何停止自动删除用户组。用户组是非常重要的表,不应删除。任何帮助将非常感激。谢谢。

hibernate spring many-to-many
1个回答
1
投票

让我们看看用户

    public class User {

        @Id
        @GeneratedValue
        private Integer id;

        @ManyToMany
        @JoinTable(name="USER_GROUP",  
            joinColumns=@JoinColumn(name="USER_ID", referencedColumnName="USER_ID"),
            inverseJoinColumns=@JoinColumn(name="GROUP_ID")
        )
        private List<Group> groupList = new ArrayList<Group>();

    }

现在我们的集团

    public class Group {

        @Id
        private String id;

        @ManyToMany(mappedBy="groupList")
        @Cascade(SAVE_UPDATE)
        private List<User> userList = new ArrayList<User>();

    }

在继续之前,让我们简单地看一下 userList 字段

    // Group.java

    @ManyToMany(mappedBy="groupList")
    @Cascade(SAVE_UPDATE)
    private List<User> userList = new ArrayList<User>();

@Cascade(SAVE_UPDATE)
表示

保存或更新每个引用的用户

mappedBy="groupList"
表示

对于每个REFERENCED用户,看它是否有对我(Group对象)的引用。如果是这样,建立我们的双向关系。所以如果你想通过 USER_GROUP 表链接 User 和 Group,每个 REFERENCED 用户都必须有一个 Group 对象的引用。

现在让我们看看 testGetUserByEmail 方法中发生了什么

    Group group = new Group(); 
    group.setId(groupId);

    // group.getUserList(); returns a empty List, right ?
    // As there is no User with reference to group in group.getUserList();
    // So NO LINK between Group and User through USER_GROUP table
    session.save(group);

    // It explains why your link is missing
    // You need to set up both sides
    user.getGroupLists().add(group);

    // Just save a User
    // Nothing else
    session.saveOrUpdate(user);

在 createUser 方法中,您有与上图相同的场景

所以我的建议是

使用双向关系时,始终使用添加便捷方法

    // Group.java
    public void addUser(User user) {
        user.getGroupList().add(this);

        getUserList().add(user);
    }
    // User.java
    public void addGroup(Group group) {
        group.getUserList().add(this);

        getGroupList().add(group);
    }

问候,

© www.soinside.com 2019 - 2024. All rights reserved.