ManyToMany assoicate删除连接表条目 [英] ManyToMany assoicate delete join table entry

查看:103
本文介绍了ManyToMany assoicate删除连接表条目的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我使用这两个实体创建一个新用户并将其关联:

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

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

@SearchableProperty
字符串userId; // '唯一标识符。它使用这种方式形成:''前缀:标识符''
字符串用户名; //用于登录应用程序的名称。
字符串电子邮件; //用户的电子邮件

@ManyToMany
@JoinTable(name =usergroup,
joinColumns = @ JoinColumn(name =userid,referencedColumnName =userId),
inverseJoinColumns = @ JoinColumn(name =groupid)

List< Group>组;


}

// Group
@Entity
@Table(name =grouptable)
public class Group实现Serializable {
@Id
String groupId //唯一标识组。
字符串描述//描述组目的的简要文本。

@ManyToMany(mappedBy =groups)
@Cascade(SAVE_UPDATE)
List< User>用户

....
}

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

将组添加到组列表非常令人满意,在用户上调用保存方法并观看休眠保存usergoup。然而,当我在保存(用户)操作后检索用户时,我有一个很大的问题,休眠自动从用户组表中自动删除条目。



这里是测试序列那一代删除用户组


  1. 保存新用户 保存新用户组
  2. $
  3. 以用户名列出的组
  4. 保存用户

  5. 通过电子邮件获取用户

  6. ol>

     
    @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地址解析协议;
    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(这不是正确的电子邮件,email,testUser.getEmail());



    $ b $ pre $ code私人用户createUser(){
    会话会话=工厂.getCurrentSession();
    字符串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);

    列表< 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();
    返回用户;
    }



     
    //存储库方法从电子邮件中获取用户
    //
    // @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();
    返回用户;
    }

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

      Hibernate:
    从$ b $删除
    usergroup
    其中
    userid =?

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



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

    解决方案

    让我们来看看用户

      public class User {

    @Id
    @GeneratedValue
    private Integer id;
    $ b @ManyToMany
    @JoinTable(name =USER_GROUP,
    joinColumns = @ JoinColumn(name =USER_ID,referencedColumnName =USER_ID),
    inverseJoinColumns = @ JoinColumn(name =GROUP_ID)

    私人列表< 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>();






    $ p

    在我们看到userList字段之前, / p>

      // Group.java 

    @ManyToMany(mappedBy =groupList)
    @级联(SAVE_UPDATE)
    私人列表<用户> userList = new ArrayList< User>();

    @Cascade(SAVE_UPDATE)表示


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


    mappedBy =groupList表示


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


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

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

    // group.getUserList();返回一个空的List,对吧?
    //因为没有用户引用group.getUserList()中的组;
    //通过USER_GROUP表,组和用户之间没有链接
    session.save(group);

    //它解释了为什么你的链接丢失
    //你需要设置双方
    user.getGroupLists()。add(group);

    //保存一个用户
    //没有其他
    session.saveOrUpdate(user);

    在createUser方法中,您的场景如上所示



    所以我的建议是


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




      // Group.java 
    public void addUser(User user){
    user.getGroupList( )。新增(本);

    getUserList()。add(user);
    }

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

    getGroupList()。add(group);
    }

    问候,


    I use these two entities to create a new user and groups it associates:

    @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  
    
        ....  
    }  
    

    On the database: usertable (id, userId, name) grouptable (id, description) usergroup(userid, groupid, groupkey)

    It's very satisfying to add Group to list of groups, call save method on User and watch hibernate save the usergoup togehter. However, I have a big problem of hibernate automatically deleting entry from the usergroup table automatically when I retrieve the User after a save(User) operation.

    Here is the test sequence that generation the deletion of usergroup

    1. save new user
    2. save new group
    3. And group to list in user
    4. save user
    5. get user from email

        @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; 
    }
    

    Before executing step 5, usergroup with automatically removed like // SQL output

    Hibernate:
    delete
    from
    usergroup
    where
    userid=? 
    

    A few thing I to note; 1. userid is NOT the pk of user object. Would that be the problem? 2. The manyTomany mapping in usergroup mapped by userid and groupid 3. It happens not just in Test. It's in development too.

    How can I stop the automatic deletion of usergroup. Usergroup is very important table and should not be deleted. Any help would be much appreciated. Thank you.

    解决方案

    Let's see User

    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>();
    
    }
    

    Now our Group

    public class Group {
    
        @Id
        private String id;
    
        @ManyToMany(mappedBy="groupList")
        @Cascade(SAVE_UPDATE)
        private List<User> userList = new ArrayList<User>();
    
    }
    

    Before going on, Let's see userList field in a nutshell

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

    @Cascade(SAVE_UPDATE) means

    Save Or Update each referenced User

    mappedBy="groupList" means

    For each REFERENCED user, see whether it has a reference to me (Group object). If so, set up our bidirectional relationship. So if you want to link User and Group through USER_GROUP table, each REFERENCED user has to have a reference to a Group object.

    Now let's see what is happening in testGetUserByEmail method

    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);
    

    In createUser method, you have the same scenario as shown above

    So my advice is

    When using bidirectional relationship, ALWAYS use a add convenience method

    // 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);
    }
    

    regards,

    这篇关于ManyToMany assoicate删除连接表条目的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆