java - 如何在 Hibernate/JPA 中的映射/子表上删除现有记录并插入新记录

标签 java spring hibernate jpa

表格

+--------------+-------------+------------+
| USER         |             |            |
| ID           | USERNAME    |            |
| 1            | Jon         |            |
| 2            | Bob         |            |
| PROJECT      |             |            |
| ID           | PROJECTNAME |            |
| 1            | Java        |            |
| 2            | DevOps      |            |
| 3            | DotNet      |            |
| 4            | Testing     |            |
| 5            | Node        |            |
| USER_PROJECT |             |            |
| ID           | USER_ID     | PROJECT_ID |
| 1            | 1           | 1          |
| 2            | 1           | 2          |
| 3            | 1           | 3          |
+--------------+-------------+------------+

类(class)


 User{
     ...
    @OneToMany(mappedBy="user", cascade=CascadeType.ALL, fetch=FetchType.LAZY, orphanRemoval=true)
        @Getter @Setter private Set<UserProject> userProjects;
    ...
    }

    Project{
        @OneToMany(mappedBy="project", cascade = CascadeType.ALL, fetch = FetchType.EAGER, orphanRemoval=true)
        @Fetch(FetchMode.JOIN)
        @Getter @Setter private Set<UserProject> userProjects;
    }

    UserProject{
        ....
        @ManyToOne
        @JoinColumn(name = "user_id")
        @Getter @Setter private User user;

        @ManyToOne
        @JoinColumn(name = "project_id")
        @Getter @Setter private Project project;

        @ManyToMany(cascade = {CascadeType.ALL}, fetch = FetchType.EAGER)
        @JoinTable(name="user_project_role",
            joinColumns={@JoinColumn(name="user_project_id")},
            inverseJoinColumns={@JoinColumn(name="role_id")})
        @Getter @Setter private Set<Role> roles;

    ...
    }

服务实现方法:

public User updateUserDetails(User user){
        User updatedUser = userDAO.findOne(user.getId());
        for(Iterator<UserProject> iterator = updatedUser.getUserProjects().iterator(); iterator.hasNext();){
            UserProject userProject = iterator.next();
            if(!user.getUserProjects().contains(userProject)){
              //I have even changed the USER_PROJECT.USER_ID constraint to NOT-NULL for this line to work
              userProject.setUser(null);
            }
        }
        return userDAO.save(updatedUser);
    }

我的 UI 提供了“添加”和“删除”用户现有项目的选项。

我打算删除并插入到 USER_PROJECT 中。但是我无法删除用户的现有项目。我只能为用户添加新选择的项目。

我在这里做错了什么? 如果不清楚,请评论。

环境 Hiberante 4.x/JPA、Spring 4.x/Spring Data JPA

最佳答案

我认为 UserProject 映射是一个明智的选择,因为角色有附加数据(如果不是,您通常不会映射该表)。

孤立删除显然无法工作,因为它被用户和项目表引用。

因此,要删除,您需要找到 UserProject 关联,将其从用户和项目的集合中删除,从持久性内容中显式删除它,提交事务。

例如类似的事情:

public User updateUserDetails(User template){
    User toUpdate = EM.find(User.class,template.getId());
    Set<UserProject> present = template.getUserProjects();//the ones should be kept
    Set<UserProject> toDel = new HashSet<>(toUpdate.getUserProjects());
    toDel.removeAll(present); //the difference so the once should be removed
    Set<UserProjcet> newOnes = new HashSet<>(present);
    newOnes.removeAll(toUpdate.getUserProjects()); //freshly added
    for (UserProject uP : toDel) {
        up.getProject().getUserProjects().remove(uP); //from each project removing reference to UserProject
        toUpdate.getUserProjects().remove(uP);
        EM.remove(uP); //removing the actuall 
    }
    toUpdate.getUserProjects().addAll(newOnes);
    return toUpdate;
}

如果您找到要删除的 UserProjects,将用户和项目设置为 null 并删除它(您仍然必须在用户项目上调用 Em.remove)而不更新列表,它也可能有效(尚不确定)。

关于java - 如何在 Hibernate/JPA 中的映射/子表上删除现有记录并插入新记录,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28616935/

相关文章:

spring - 在单个事务中更新数据库并发送 JMS 消息?

java - 如何将 Camunda 引擎和 admin/tasklist/cockpit 嵌入到我自己的 Spring Security webapp 中?

java - hibernate 和日期类型 : length attribute

java - Hibernate "no session or session was closed"即使在事务方法中绑定(bind)了 session

java - ChangeListener<? 的未选中警告super TableRow>-参数

java - read() 和 readObject() 的问题

java - 如何在 Spring MVC 中的同一 @RequestMapping 中为参数映射不同的值?

java - 在 Hibernate 中使用预定义的前缀填充 Id 列

java - JBoss 7 启动失败

java - 单击按钮时将焦点设置到 EditText