我有三张 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/