Sql 加入3个表Hibernate&;JPA
我有三张桌子,我想加入他们,这让我发疯 选项卡:任务 项目 用户 它们之间都有一种多对多关系:就像项目有多个用户,反之亦然,任务也有多个用户,反之亦然,项目和用户也是如此 我正试图找到一种在JPA和Hibernate中实现这一点的方法,我有两种选择: **1**像这样加入3个实体: 项目:Sql 加入3个表Hibernate&;JPA,sql,spring,hibernate,jpa,spring-data,Sql,Spring,Hibernate,Jpa,Spring Data,我有三张桌子,我想加入他们,这让我发疯 选项卡:任务 项目 用户 它们之间都有一种多对多关系:就像项目有多个用户,反之亦然,任务也有多个用户,反之亦然,项目和用户也是如此 我正试图找到一种在JPA和Hibernate中实现这一点的方法,我有两种选择: **1**像这样加入3个实体: 项目: @ManyToMany(fetch = FetchType.EAGER, cascade = { CascadeType.DETACH,
@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<>();
任何帮助都将非常感激。谢谢。应按以下方式实施: 项目类
@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用于映射键的列,这里是项目实体
@ElementCollection
如果映射的值为@Embedded,则使用
@JoinTable
定义实体类与映射值中定义的实体之间的关系(这里是任务和用户之间的关系)
所有targetEntity都是冗余的,因为您使用了具有已定义泛型类型的集合
此外,您不必像这样配置3个类。据我所知,您只需要一个包含这3个类之间关系的表。
因此,只需定义一个称为协作的实体,如下所示:
@Entity
public class Collaboration{
@ManyToOne
private User user;
@ManyToOne
private Task task;
@ManyToOne
private Project project;
}
使用分离的协作实体,您可以找到给定用户的所有协作
如果没有这个实体,您可以编写一个查询来查找与给定用户相关的所有任务,当然,还可以自己在java代码中收集项目和任务。
查询将类似于
'Select t from Task t join projectUserMap m where m = :user '
我只是浏览了一下您的配置,发现了很多错误和冗余。请研究更多关于JPA集合映射的信息,以深入了解这一点。这是因为我不知道如何重新定义以及如何连接这三个表。我一开始使用project和user很容易成功,但使用三元关联有点困难。我不使用mappedBy,因为我想控制删除操作的发生方式。这是一个很大的错误你在干什么。mappedBy和coltrolling删除与eash other没有任何关系。在双向关联中,一侧必须是相反的一侧,因此使用mappedBy。你们在这项任务中大发雷霆也没什么意义。如果您有三个多个关联,则需要三个不同的联接表。感谢mappedBy注释。但这正是我要逃避的。我不想做三个联接表。我想我会创建一个连接表,其中包含3个表的ID,如:1_Project/1_Task/1_USER,如上一个SQL查询中所示。如果该表有三列,则它不是两个实体之间的连接表,您需要将其映射为一个实体。感谢您的响应。我不知道是谁否决了你,但不是我!如果您想在这里解释一下,这三个表是链接的??我的观点是,如果我调用该表上的查询
collaboration
,以获取给定用户的任务和项目,我将获得它们?好的。我只是关心我是否能帮助你理解。非经验用户的否决票对我来说不是问题。如果出了什么问题,请在此询问。我根据您的问题更新了我的答案。如果我的答案符合您的要求,请将其标记为正确答案,因为可能其他人在corse的未来也会有相同的问题。我只是在实现它,我会看到的。Thanks@thanhngo此查询不涉及项目和用户,只提供用户。我们如何使用JPQL查询找到键和值?
targetEntity = User.class
@Entity
public class Collaboration{
@ManyToOne
private User user;
@ManyToOne
private Task task;
@ManyToOne
private Project project;
}
'Select t from Task t join projectUserMap m where m = :user '