多对多关联删除连接表条目

时间:2010-01-17 09:04:13

标签: hibernate spring many-to-many

我使用这两个实体来创建一个新用户并将其分组:

@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  

    ....  
}  

在数据库上: usertable(id,userId,name) grouptable(id,description) usergroup(userid,groupid,groupkey)

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

以下是生成用户组删除的测试序列

  1. 保存新用户
  2. 保存新群组
  3. 并在用户列出的组
  4. 保存用户
  5. 从电子邮件中获取用户
  6.     @Test
        @Transactional
        public void testGetUserByEmail(){
            Session session = factory.getCurrentSession(); 
    
            String email = "sarah.silverman@comedycentral.com"; 
            User user = createUser(); 
            user.setWeCanContact(true); 
            user.setPartnersCanContact(false); 
            user.setAgreedTerms(false); 
            user.setReferer("Laura");
    
            String groupId = "AARP"; 
            String description = "Appletalk Address Resolution Protocol"; 
            Group group1 = new Group(); 
            group1.setGroupId(groupId); 
            group1.setDescription(description); 
            session.save(group1); 
            session.flush(); 
            user.getGroupLists().add(group1); 
            session.saveOrUpdate(user); 
    
            User testUser = userRepository.getUserByEmail(email);
            assertNotNull(testUser); 
            assertEquals("It's not the correct email", email, testUser.getEmail()); 
        }
    
        private User createUser(){
            Session session = factory.getCurrentSession(); 
            String userId = "UB:2010"; 
            String userPassword = "sarah"; 
            String realName = "Sarah Silverman"; 
            String email = "sarah.silverman@comedycentral.com"; 
    
            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; 
        }
    
    // Repository Method to get user from email
    // 
    //  @NamedQuery(name="user.findByEmail",
    //       query="SELECT u FROM User u " +
    //    "LEFT JOIN FETCH u.groupLists " +
    //              "WHERE upper(u.email) = :email")
    
    public User getUserByEmail(String email) {
        Session session = sessionFactory.getCurrentSession(); 
        Query query = session.getNamedQuery("user.findByEmail");
        query.setParameter("email", email.toUpperCase());
        User user = (User)query.uniqueResult();
        return user; 
    }
    

    在执行第5步之前,usergroup会自动删除 // SQL输出

    Hibernate:
    delete
    from
    usergroup
    where
    userid=? 
    

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

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

1 个答案:

答案 0 :(得分:3)

让我们看看用户

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用户,查看它是否具有对我的引用(组对象)。如果是这样,请设置我们的双向关系。因此,如果要通过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);
}

的问候,