Varlık ve dizeler arasındaki M: N ilişkisine takıldım. Bir kullanıcının birden fazla rolü olabilir ve her rol birden fazla kullanıcıya atanabilir. Rol sadece bir dizedir. Roller iki sütun içeren tabloda bulunur: roleId
ve roleName
.
İki varlık oluşturdum ama kesinlikle işe yaramayacağım. İlk varlık kullanıcıdır:
@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 roles;
@Transient
private Collection roleNames;
public String getLogin() {
return login;
}
public String getPassword() {
return password;
}
@PostLoad
void prepareRoleNames() {
roleNames = new HashSet(roles.size());
for (UsersToRoles mapping : roles)
roleNames.add(mapping.getNameOfRole());
}
public Collection getRoles() {
return roleNames;
}
}
İkincisi, bağlantı tablosuyla ilişkili varlıktır:
@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 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);
}
}
Ve sorun şu ki, roleName
koleksiyonu her zaman boş. Onu işe alamıyorum. Tablo adında @CollectionTable
açıklamasında bir hata yaptığımda, hala çalışır. JPA altkomisyonu hiç almıyor. Tablo UsersToRoles
ile birleştirilen kullanıcının tablosundan seçim yapar, ancak userRoles
tablosuna birleştirme eksik.
Bunu yapabilir miyim? Başka hevesle getirilmiş koleksiyonlar içeren hevesle topluluğun koleksiyonunu alabilir miyim?