我有一个Spring MVC应用程序来处理可以托管一个或多个用户的用户和结构。 我使用Hibernate来保持持久性,并且我对用户和结构之间的一对多关系存在一些问题。
这是我的用户模型:
@Entity
@Table(name="USERS")
public class User extends DatabaseEntity {
@Id @GeneratedValue
private Long id = 0L;
@Column
@NotEmpty
private String firstName;
@Column
private String lastName;
@Column
private Date birthDate;
@Column
private String nation;
@Column
private String town;
@Column
private String idNumber;
@Column(unique = true)
private String email;
@Column String resetPasswordToken = "";
@Column
private String password;
@Column
private String avatarUrl;
@Column @Enumerated(EnumType.STRING)
private Role role;
@ManyToOne
@JoinColumn(name = "STRUCTURE_ID")
@Cascade({CascadeType.DETACH})
private Structure structure;
public enum Role {
ADMINISTRATOR,
SPECIALIST,
PATIENT,
DOCTOR,
CARE_GIVER
}
public User() {
birthDate = new Date();
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
public Date getBirthDate() {
return birthDate;
}
public void setBirthDate(Date birthDate) {
this.birthDate = birthDate;
}
public String getNation() {
return nation;
}
public void setNation(String nation) {
this.nation = nation;
}
public String getTown() {
return town;
}
public void setTown(String town) {
this.town = town;
}
public String getIdNumber() {
return idNumber;
}
public void setIdNumber(String idNumber) {
this.idNumber = idNumber;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public String getAvatarUrl() {
return avatarUrl;
}
public void setAvatarUrl(String avatarUrl) {
this.avatarUrl = avatarUrl;
}
public Role getRole() {
return role;
}
public void setRole(Role role) {
this.role = role;
}
public Set<Group> getGroups() {
return null;
}
public void setGroups(Set<Group> groups) {
}
public Set<Group> getCreatedGroups() {
return null;
}
public void setCreatedGroups(Set<Group> createdGroups) {
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public Set<HangoutUser> getHangoutUsers() {
return null;
}
public void setHangoutUsers(Set<HangoutUser> hangoutUsers) {
}
public String getResetPasswordToken() {
return resetPasswordToken;
}
public void setResetPasswordToken(String resetPasswordToken) {
this.resetPasswordToken = resetPasswordToken;
}
public Group getStructure() {
return structure;
}
public void setStructure(Structure structure) {
this.structure = structure;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (!(o instanceof User)) return false;
User user = (User) o;
if (!email.equals(user.email)) return false;
if (!id.equals(user.id)) return false;
return true;
}
@Override
public int hashCode() {
Long res = id;
if(id == null)
res = 0L;
int result = res.hashCode();
result = 31 * result + email.hashCode();
return result;
}
}
这是我的结构模型:
@Entity
@Table(name = "STRUCTURES")
public class Structure extends DatabaseEntity {
@Id @GeneratedValue
Long id = 0L;
@Column
String name;
@Column
String address;
@Column
String city;
@Column
String state;
@OneToMany(mappedBy = "structure", fetch = FetchType.EAGER)
@Cascade({CascadeType.DELETE})
Set<User> users = new HashSet<User>();
public Long getId()
{
return id;
}
public void setId(Long id)
{
this.id = id;
}
public String getName()
{
return name;
}
public void setName(String name)
{
this.name = name;
}
public String getAddress()
{
return address;
}
public void setAddress(String address)
{
this.address = address;
}
public String getCity()
{
return city;
}
public void setCity(String city)
{
this.city = city;
}
public String getState()
{
return state;
}
public void setState(String state)
{
this.state = state;
}
public Set<User> getUsers()
{
return this.users;
}
public void setUsers(Set<User> users)
{
this.users = users;
}
}
我的问题是,当我尝试查找所有评估值为STRUCTURE_ID的用户时,我得到一个Hibernate Exception,如下所示:
org.springframework.orm.hibernate3.HibernateSystemException:找到同一集合的两个表示:it.amtservices.livinglab.model.Group.users;嵌套异常是org.hibernate.HibernateException:找到了两个相同集合的表示:it.amtservices.livinglab.model.Structure.users 在org.springframework.orm.hibernate3.SessionFactoryUtils.convertHibernateAccessException(SessionFactoryUtils.java:690)...
我该怎么做才能解决这个问题?我已经尝试了很多方法,但没有解决。
我粘贴了UsersRepository和StructureRepository的抽象存储库实现:
@Transactional
public abstract class AbstractRepository<Model extends DatabaseEntity>
{
Logger logger = Logger.getLogger(this.getClass().getSimpleName());
@PersistenceContext
EntityManager em;
protected Class<Model> ModelClass;
protected List<Model> findBy(String parameterName, Object parameterValue)
{
Query q = em.createQuery("select t from " + ModelClass.getSimpleName() + " t where t." + parameterName + " = :" + parameterName);
q.setParameter(parameterName, parameterValue);
List<Model> results = null;
try
{
results = q.getResultList();
}
catch (Exception e)
{
return null;
}
return results;
}
protected List<Model> findBy(Map<String, Object> parameters)
{
String whereClause = "";
for (String key : parameters.keySet())
{
if (!whereClause.equals("")) whereClause += " and ";
whereClause += "t." + key + " = :" + key;
}
Query q = null;
try
{
q = em.createQuery("select t from " + ModelClass.getSimpleName() + " t where " + whereClause);
}
catch (Exception e)
{
e.printStackTrace();
}
for (String key : parameters.keySet())
{
q.setParameter(key, parameters.get(key));
}
List<Model> results = null;
try
{
results = q.getResultList();
}
catch (Exception e)
{
return null;
}
return results;
}
protected Model findOneBy(String parameterName, Object parameterValue)
{
List<Model> results = findBy(parameterName, parameterValue);
if (results != null && results.size() > 0) return results.get(0);
return null;
}
protected Model findOneBy(Map<String, Object> parameters)
{
List<Model> results = findBy(parameters);
if (results != null && results.size() > 0) return results.get(0);
return null;
}
public Model findOne(Long id)
{
return findOneBy("id", id);
}
public List<Model> findAll()
{
Query q = em.createQuery("select t from " + ModelClass.getSimpleName() + " t");
List<Model> results = null;
try
{
results = q.getResultList();
}
catch (Exception e)
{
return null;
}
return results;
}
public boolean save(Model model)
{
try
{
Model newModel = em.merge(model);
if (model.getId() == 0L) model.setId(newModel.getId());
}
catch (Exception e)
{
logger.error(ModelClass.getSimpleName() + "Repository: " + e.getMessage());
return false;
}
return true;
}
public void save(List<Model> models)
{
for (Model model : models)
{
save(model);
}
}
public void delete(Model model)
{
delete(model.getId());
}
public void delete(Long id)
{
beforeDelete(findOne(id));
try
{
Query q = em.createQuery("delete from " + ModelClass.getSimpleName() + " t where t.id = :id").setParameter("id", id);
q.executeUpdate();
}
catch (Exception e)
{
logger.error(ModelClass.getSimpleName() + "Repository: " + e.getMessage());
}
}
public void delete(Collection<Model> models)
{
for (Model model : models)
{
delete(model.getId());
}
}
public void deleteAll()
{
for (Model model : findAll())
{
delete(model);
}
}
public abstract void beforeDelete(Model model);
public List<Model> find(List<Long> ids)
{
List<Model> models = new ArrayList<Model>();
for (Long id : ids)
{
Model model = findOne(id);
if (model != null) models.add(model);
}
return models;
}
}
谢谢!