Hibernate返回重复,因为另一个表具有重复值

时间:2012-07-03 21:41:57

标签: hibernate annotations mapping duplicates criteria

所以我有一个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

1 个答案:

答案 0 :(得分:13)

来自条件查询的重复行问题的经典“修复”,只要您不尝试将其与分页相结合,这可能会有用,就是添加

criteria.setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY);

我相信这种情况正在发生在您的情况中,因为用户角色的加载很少。将其变为懒惰也可能有效,并且如果您需要分页,则继续工作。

设置fetch = FetchType.EAGER指示您希望在检索用户时始终为用户加载所有角色的hibernate,它通过始终连接到角色表来完成。

不幸的是,sql导致多个记录具有相同的用户(每个角色一个),然后在运行sql之后必须在Java中理顺它,这就是结果转换器的作用。

更不幸的是,如果你想使用简单的休眠标准以最自然的方式使用分页,使用criteria.setFirstResultcriteria.setMaxResults,事情会以错误的顺序发生,所以这些查询需要结果变压器以避免重复只是不要向右翻页。

为了更好地理解所有hibernate sql生成,我建议将this answer中描述的生成的sql的日志记录打开到另一个SO休眠问题。