三元關係,我有四個tables.entities,實現在休眠
- 用戶
- 項目
- 角色
- UserProjectRole
我的情況或關係,在一個項目中,一個用戶有很多角色。 我很困惑地在上面的hibernate實體中映射關係。 需要一些幫助。
在此先感謝。
三元關係,我有四個tables.entities,實現在休眠
我的情況或關係,在一個項目中,一個用戶有很多角色。 我很困惑地在上面的hibernate實體中映射關係。 需要一些幫助。
在此先感謝。
有很多方法可以實現與Hibernate的所謂三元關係,或者利用"simple" map或者使用中間實體/表實現關聯。你的用例決定哪個是正確的。這取決於數據如何存儲以及您將如何(經常)讀取它。報告也是一個重要的用例。
如果您希望允許許多用戶 - 項目 - 角色組合,則映射(例如用戶實體上的映射)並不十分合適,因爲您的密鑰可能是項目或角色,並且密鑰只能出現一次。儘管如此,每個關係條目在系統中都應該是唯一的,所以在這種情況下,我傾向於至少具有一些獨特約束的中間表。
的「快速和骯髒」的方式將是一個實體,如:
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.ManyToOne;
import javax.persistence.Table;
import javax.persistence.UniqueConstraint;
@Entity
@Table(uniqueConstraints = @UniqueConstraint(columnNames={"user_id", "project_id", "role_id"}))
public class UserProjectRoleSimple {
@Id
@GeneratedValue
private Long id;
@ManyToOne
private User user;
@ManyToOne
private Project project;
@ManyToOne
private Role role;
// you also need constructors, getters, equals, hashcode and stuff
}
另一個(更好的)方法是使用關係對象標識符作爲複合鍵。這有點冗長,但你不需要額外的代理鍵,所以你的連接表更乾淨。
import java.io.Serializable;
import javax.persistence.Embeddable;
import javax.persistence.EmbeddedId;
import javax.persistence.Entity;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.validation.constraints.NotNull;
import org.hibernate.annotations.Immutable;
@Entity
@Immutable
public class UserProjectRole {
protected UserProjectRole() {
}
public UserProjectRole(final User user, final Project project, final Role role) {
this.userProjectRoleId = new UserProjectRoleId(user, project, role);
this.user = user;
this.project = project;
this.role = role;
}
@EmbeddedId
protected UserProjectRoleId userProjectRoleId;
@ManyToOne
@JoinColumn(name = "userId", insertable = false, updatable = false)
private User user;
@ManyToOne
@JoinColumn(name = "projectId", insertable = false, updatable = false)
private Project project;
@ManyToOne
@JoinColumn(name = "roleId", insertable = false, updatable = false)
private Role role;
public User getUser() {
return user;
}
public Project getProject() {
return project;
}
public Role getRole() {
return role;
}
@Embeddable
static class UserProjectRoleId implements Serializable {
private static final long serialVersionUID = 7994974851694559677L;
@NotNull
private Long userId;
@NotNull
private Long projectId;
@NotNull
private Long roleId;
protected UserProjectRoleId() {
}
protected UserProjectRoleId(final User user, final Project project, final Role role) {
this.userId = user.getId();
this.projectId = project.getId();
this.roleId = role.getId();
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((projectId == null) ? 0 : projectId.hashCode());
result = prime * result + ((roleId == null) ? 0 : roleId.hashCode());
result = prime * result + ((userId == null) ? 0 : userId.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
UserProjectRoleId other = (UserProjectRoleId) obj;
if (projectId == null) {
if (other.projectId != null)
return false;
} else if (!projectId.equals(other.projectId))
return false;
if (roleId == null) {
if (other.roleId != null)
return false;
} else if (!roleId.equals(other.roleId))
return false;
if (userId == null) {
if (other.userId != null)
return false;
} else if (!userId.equals(other.userId))
return false;
return true;
}
}
}
該映射也很簡單,只有非凡的部分是@JoinColumn(name = "...Id", insertable = false, updatable = false)
增加。有了它,您可以使用您的映射實體(用於導航目的),而不需要存儲兩次。
UserProjectRole與其他實體的關係如何。 OR UserProjectRole表的使用情況? –
我將用它來存儲哪個用戶在哪個項目中具有哪個角色。例如,用戶「A」在項目「P」中具有「ScrumMaster」角色。 –
用戶可以在一個項目中擁有多個角色嗎?例如用戶A既是Scrummaster又是項目P的開發人員? – dcsohl