2016-08-13 49 views
1

我有三張桌子,我想加入他們,這讓我瘋狂。加入3桌Hibernate和JPA

Tabels:任務 項目 用戶

他們都有一個許多一對多它們之間的關係:喜歡的項目有多個用戶,反之亦然,也任務有多個用戶反之亦然,項目和用戶也是如此。

我試圖找到一種方法來實現,在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<>(); 

但這裏不到風度似乎工作

:創建一個第四實體並將其命名爲合作者,然後試圖找到實現此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 

任何幫助將許多 apreciated。謝謝。

+0

我只是看看你的配置,找出很多錯誤和冗餘。請詳細瞭解JPA Collection Mapping以深入瞭解這一點。 –

+0

這是因爲我沒有不解決以及如何加入這三個表格。我一開始就很容易成功地獲得了項目和用戶的成功,但是通過三元關聯,它有點難。 –

+1

*我不使用mappedBy,因爲我想控制刪除操作發生的方式。*:這是一個很大的錯誤,你正在做。 mappedBy和coltrolling的刪除與eash沒有任何關係。在雙向關聯中,一方**必須**是反面,因此使用mappedBy。你在任務中挺身而出也沒有什麼意義。如果您有三個ManyToMany關聯,則需要3個不同的連接表。 –

回答

1

應實行象下面這樣:

工程類

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

User類

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

Task類

@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 

用於如果所述映射的值是@Embeddable

@JoinTable 

定義了與在地圖的值定義的實體實體類之間的關係(這裏是任務和用戶之間的關係)。

targetEntity = User.class 

所有targetEntity都是多餘的,因爲您使用具有定義的泛型類型的集合。

此外,您不必像這樣配置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 ' 
+0

感謝您的回覆。我不知道誰低估了你,但這不是我!如果你在這裏解釋一下,這三張表是相關的?我的觀點是,如果我在該表上調用一個查詢'協作'來獲取**給定用戶**的任務**和**項目**,我會得到它們? –

+0

好的。我只是在乎我能否幫助你理解。來自非體驗用戶的downvote對我來說不是問題。請問這裏是否有問題。我更新了我的回答,關於你的問題。 –

+0

如果我的答案滿足您的要求,請將其標記爲正確的,因爲可能其他人將來會有相同的問題 –