【问题标题】:Returning a list from a ManyToMany relationship?从多对多关系返回列表?
【发布时间】:2011-03-09 04:07:16
【问题描述】:

我有两个表:用户和角色。一个用户可能有更多的角色,所以这是一个多对多关系。 我用 Netbeans 生成了实体类,它们看起来像这样:

@Table(name = "users")
public class Users implements Serializable {
    @Id
    @Basic(optional = false)
    @Column(name = "user_name")
    private String userName;
    @JoinTable(name = "user_roles", joinColumns = {
        @JoinColumn(name = "user_name", referencedColumnName = "user_name")}, inverseJoinColumns = {
        @JoinColumn(name = "role_name", referencedColumnName = "role_name")})
    @ManyToMany(fetch = FetchType.LAZY)
    private Collection<Roles> rolesCollection;

(等)

@Table(name = "roles")
public class Roles implements Serializable {
    @Id
    @Basic(optional = false)
    @Column(name = "role_name")
    private String roleName;
    @ManyToMany(mappedBy = "rolesCollection", fetch = FetchType.LAZY)
    private Collection<Users> usersCollection;

这是我的问题:我想在一个表中列出所有用户,并为每个用户列出他们拥有的所有角色。 我想不出解决办法。如何引用 JPQL 中的集合?如何退回收藏?这可能吗?

更糟糕的是,我有自己的类,我想用它在我的 JSF 页面上显示结果。这是当前查询:

Query query = em.createQuery("SELECT NEW UserListQueryObject"
        + "(u.userName, ...)"
        + " FROM Users u",
        UserListQueryObject.class);
List<UserListQueryObject> users = query.getResultList();

它适用于简单的属性和 OneToOne 关系。但不适用于多对多。我尝试像这样加入:

Query query = em.createQuery("SELECT NEW UserListQueryObject"
        + "(u.userName, ...., r.roleName)"
        + " FROM Users u JOIN u.rolesCollection r",
        UserListQueryObject.class);

...但是运行时抱怨“r”附近的语法错误,以及 r.roleName。它想返回一个角色,但我需要一个用户的所有角色!

我也不是 SQL 方面的专家,因此解决方案很可能很简单……在阅读了“Pro JPA 2……”一书之后,我还是被卡住了。感谢您的帮助。

【问题讨论】:

    标签: jakarta-ee jpql jpa-2.0


    【解决方案1】:

    我想在一个表中列出所有用户,并为每个用户列出他们拥有的所有角色。 (...)

    如果要在单个查询中读取多个对象,可以使用 join fetch

    SELECT u FROM Users u JOIN FETCH u.rolesCollection
    

    这将执行一个内部联接,这意味着这将过滤结果集中没有角色的任何用户。

    为避免上述行为,请使用 OUTER 连接:

    SELECT u FROM Users u LEFT JOIN FETCH u.rolesCollection
    

    【讨论】:

    • 完美! JOIN FETCH 完美运行。它还可以与 NEW 运算符一起使用,返回相同记录的次数是用户拥有的角色的次数(=类似 SQL 的行为)。仍然不起作用的是使用 NEW 运算符,以便它在构造函数中接受集合参数(例如 u.rolesCollection)。但这可能是另一个问题。再次感谢!
    • 嗯,我发现了这个:simonmartinelli.blogspot.com/2009/06/…,这意味着我想要的东西是不可能的。哦,好吧。
    • @egbokul:嗯,你自己找到了答案:这是不可能的。
    猜你喜欢
    • 1970-01-01
    • 2018-01-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-06-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多