所以我有一个Users表,Projects表和User_Roles表。我有一个用户连接到2个项目,但是当我只有一个角色时,它会返回这2个项目,但如果我有2个角色,则返回4个角色(2x2个项目)。我该如何阻止这个
这是我返回用户
项目列表的代码@Override
public List<Project> retrieve(User user) {
Criteria criteria = super.createCriteria();
criteria.addOrder(Order.desc("date"));
criteria.createCriteria("users").add(Restrictions.eq("id", user.getId()));
return (List<Project>) criteria.list();
}
用户类
中的映射@ManyToMany(cascade = CascadeType.ALL)
@JoinTable(name = "Users_Projects",
joinColumns = @JoinColumn(name = "UserID"), inverseJoinColumns = @JoinColumn(name = "ProjectID"))
public List<Project> getProjects() {
return projects;
}
@ElementCollection(fetch = FetchType.EAGER)
@Enumerated(EnumType.STRING)
@Column(name = "RoleType")
@JoinTable(name = "User_Roles", joinColumns = @JoinColumn(name = "UserID"))
public Set<Role> getRoles() {
return roles;
}
有什么建议吗?
TNX
答案 0 :(得分:13)
来自条件查询的重复行问题的经典“修复”,只要您不尝试将其与分页相结合,这可能会有用,就是添加
criteria.setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY);
我相信这种情况正在发生在您的情况中,因为用户角色的加载很少。将其变为懒惰也可能有效,并且如果您需要分页,则继续工作。
设置fetch = FetchType.EAGER
指示您希望在检索用户时始终为用户加载所有角色的hibernate,它通过始终连接到角色表来完成。
不幸的是,sql导致多个记录具有相同的用户(每个角色一个),然后在运行sql之后必须在Java中理顺它,这就是结果转换器的作用。
更不幸的是,如果你想使用简单的休眠标准以最自然的方式使用分页,使用criteria.setFirstResult
和criteria.setMaxResults
,事情会以错误的顺序发生,所以这些查询需要结果变压器以避免重复只是不要向右翻页。
为了更好地理解所有hibernate sql生成,我建议将this answer中描述的生成的sql的日志记录打开到另一个SO休眠问题。