我一直卡在實體和字符串之間的M:N關係中。用戶可以有多個角色,每個角色可以分配給多個用戶。角色只是一個字符串。表中包含兩列角色:roleId
和roleName
。獲取包含其他熱切收集的實體的熱切收集
我創建了兩個實體,但我完全無法使它工作。第一實體的用戶:
@Entity
@Table(name="appUsers")
public class UserEntity {
@Id
private String login;
private String password;
@OneToMany(fetch=FetchType.EAGER,mappedBy="user") //we always need to load user's roles
private Collection<UsersToRoles> roles;
@Transient
private Collection<String> roleNames;
public String getLogin() {
return login;
}
public String getPassword() {
return password;
}
@PostLoad
void prepareRoleNames() {
roleNames = new HashSet<String>(roles.size());
for (UsersToRoles mapping : roles)
roleNames.add(mapping.getNameOfRole());
}
public Collection<String> getRoles() {
return roleNames;
}
}
二是與連接表相關實體:
@Entity
@IdClass(UsersToRolesId.class)
public class UsersToRoles {
@Id
@SuppressWarnings("unused")
@Column(name="login")
private String login;
@Id
@SuppressWarnings("unused")
@Column(name="roleId")
private int roleId;
@ElementCollection(fetch=FetchType.EAGER)
@CollectionTable(name="userRoles", joinColumns={@JoinColumn(name="roleId")})
private List<String> roleName;
@ManyToOne
@JoinColumn(name="login")
@SuppressWarnings("unused")
private UserEntity user;
public String getNameOfRole() {
if (roleName.isEmpty())
throw new CommonError("Role name for roleId=" + roleId, AppErrors.ACCESSOR_UNAVAILABLE);
return roleName.get(0);
}
}
class UsersToRolesId {
private String login;
private int roleId;
/**
* Implicit constructor is not public. We have to
* declare public non-parametric constructor manually.
*/
public UsersToRolesId() {
}
@Override
public int hashCode() {
return 17*login.hashCode() + 37*roleId;
}
@Override
public boolean equals(Object obj) {
if (!(obj instanceof UsersToRolesId))
return false;
UsersToRolesId ref = (UsersToRolesId)obj;
return (this.login.equals(ref.login) && this.roleId == ref.roleId);
}
}
而問題是,該roleName
集合總是空。我無法得到它的工作。當我在@CollectionTable
註釋中輸入表名時出錯,它仍然有效。 JPA根本不會獲取子集合。它從與表UsersToRoles
加入的用戶表中選擇,但缺少表userRoles
的加入。
我可以這樣做嗎?我能否熱切地收集包含另一個熱切獲取的集合的實體?