sql - 加入 3 个表 Hibernate & JPA

标签 sql spring hibernate jpa spring-data

我有三张 table ,我想加入他们,这让我发疯。

标签:任务
项目
用户

他们都有一个 多对多 它们之间的关系:就像项目有多个用户,反之亦然,任务有多个用户,反之亦然,项目和用户也是如此。

我试图找到一种在 JPA 和 Hibernate 中实现它的方法,我有两个选择:
** 1 ** 像这样加入 3 个实体:

项目 :

   @ManyToMany(fetch = FetchType.EAGER, 
    cascade =
    {
            CascadeType.DETACH,
            CascadeType.MERGE,
            CascadeType.REFRESH,
            CascadeType.PERSIST
    },
    targetEntity = User.class)
  @JoinTable(name = "Collaborators", 
           joinColumns = @JoinColumn(name = "ProjectFk", referencedColumnName = "id", updatable=false, nullable=false), 
           inverseJoinColumns = @JoinColumn(name = "UserFk", referencedColumnName = "id", updatable=false, nullable=false))
  private Set<User> users = new HashSet<>();

用户 :
    @ManyToMany(fetch = FetchType.EAGER, 
            cascade =
                {
                        CascadeType.DETACH,
                        CascadeType.MERGE,
                        CascadeType.REFRESH,
                        CascadeType.PERSIST
                },
                targetEntity = Project.class)
    @JoinTable(name = "Collaborators", 
           joinColumns = @JoinColumn(name = "UserFk", referencedColumnName = "id", updatable=false, nullable=false), 
           inverseJoinColumns = @JoinColumn(name = "ProjectFk", referencedColumnName = "id", updatable=false, nullable=false))
    private Set<Project> projects = new HashSet<>();

任务 :
    @ManyToMany(fetch = FetchType.EAGER, 
        cascade =
        {
                CascadeType.DETACH,
                CascadeType.MERGE,
                CascadeType.REFRESH,
                CascadeType.PERSIST
        },
        targetEntity = User.class)
    @JoinTable(name = "Collaborators", 
       joinColumns = @JoinColumn(name = "TaskFk", referencedColumnName = "id", updatable=false, nullable=false), 
       inverseJoinColumns = @JoinColumn(name = "ProjectFk", referencedColumnName = "id", updatable=false, nullable=false))
    @MapKeyJoinColumn(name = "User_id")
    @ElementCollection
    private Map<Project, User> projectUserMap = new HashMap<>();

但在这里它似乎不起作用

2 :创建第四个实体并将其命名为 合作者 然后尝试找到实现此 SQL 查询的方法:
select * from (
select user.id, Project.id, Task.id
inner join Project on user.join_key = Project.join_key
inner join  Task  on task.join_key = = Project.join_key
) collaborator

任何帮助都是 赞赏。谢谢。

最佳答案

应该像下面这样实现:

项目类(class)

 @Entity
public class Project extends ABaseEntity{

private Set<User> users = new HashSet<>();

@ManyToMany
@JoinTable(name = "Collaborators",
        joinColumns = @JoinColumn(name = "Project_ID", referencedColumnName = "id", updatable=false, nullable=false),
        inverseJoinColumns = @JoinColumn(name = "User_ID", referencedColumnName = "id", updatable=false, nullable=false))
public Set<User> getUsers() {
    return users;
}

public void setUsers(Set<User> users) {
    this.users = users;
}
}

用户类别
@Entity
@Table(name = "EMA_USER")
public class User extends ABaseEntity {

private Set<Project> projects = new HashSet<>();


@ManyToMany(fetch = FetchType.EAGER,
        cascade = CascadeType.ALL,
        targetEntity = Project.class)
@JoinTable(name = "Collaborators",
        joinColumns = @JoinColumn(name = "User_ID", referencedColumnName = "id", updatable = false, nullable = false),
        inverseJoinColumns = @JoinColumn(name = "Project_ID", referencedColumnName = "id", updatable = false, nullable = false))
public Set<Project> getProjects() {
    return projects;
}

public void setProjects(Set<Project> projects) {
    this.projects = projects;
}
}

任务类
@Entity
public class Task extends ABaseEntity{

private Map<Project, User> projectUserMap = new HashMap<>();

@ManyToMany(
        fetch = FetchType.EAGER,
        cascade = CascadeType.ALL
)
@JoinTable(
        name = "Collaborators",
        joinColumns = @JoinColumn(name = "Task_ID", referencedColumnName = "id", updatable = false, nullable = false),
        inverseJoinColumns = @JoinColumn(name = "User_ID", referencedColumnName = "id", updatable = false, nullable = false)
)
@MapKeyJoinColumn(name = "Project_Id")
public Map<Project, User> getProjectUserMap() {
    return projectUserMap;
}

public void setProjectUserMap(Map<Project, User> projectUserMap) {
    this.projectUserMap = projectUserMap;
}
}

您的任务类有什么问题:
@MapKeyJoinColumn(name = "User_id")

@MapKeyJoinColumn 用于映射键的列,这里是项目实体。
@ElementCollection

如果 map 的值为@Embeddable 则使用
@JoinTable

定义实体类与在 Map 值中定义的实体之间的关系(这里是任务和用户之间的关系)。
 targetEntity = User.class

所有 targetEntity 都是多余的,因为您使用了具有定义泛型类型的集合。

此外,您不必像这样配置 3 个类。据我了解,您只需要一个包含这 3 个类之间关系的表。
所以只需定义一个名为 Collaboration 的实体,如下所示:
@Entity
public class Collaboration{
  @ManyToOne
  private User user;
  @ManyToOne
  private Task task;
  @ManyToOne
  private Project project;
}

使用分离的 Collaboration 实体,您可以找到给定 User 的所有协作。

如果没有这个实体,您可以编写一个查询来查找与给定用户相关的所有任务,然后当然可以自己在 java 代码中收集项目和任务。
查询将类似于
 'Select t from Task t join projectUserMap m where m = :user '

关于sql - 加入 3 个表 Hibernate & JPA,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38934436/

相关文章:

java - 自动获取SQL查询中要使用的列(Hibernate/Mybatis/自制)? - 创建图书馆的想法

mysql - 为什么我的 SQL 查询没有使用表的复合索引?

asp.net - SQL如何在一列中使用ORDER BY语句

sql - 查询某行对应于另一个表中多行数据的内容的最佳方法

java - Spring MVC - 没有DAO服务层,如何获取当前 session 以进行条件查询

Java\Hibernate\ManyToOne\Ordering

mysql - 按季度和按 customer_type 在 mysql 中汇总数据(按中位数)

java - JSR 250 方法级别安全性在 Spring MVC 中不起作用

java - Spring的Singleton作用域bean在Web应用程序中的表现如何?

java - 如何使用hibernate在HQL中使用子查询