如何将本机查询的结果集映射到实体中的变量

Posted

技术标签:

【中文标题】如何将本机查询的结果集映射到实体中的变量【英文标题】:How to Map Result Set of Native Query to Variable in Entity 【发布时间】:2015-06-26 19:02:40 【问题描述】:

我有两个实体,Users 和 Annotations,我想将 Annotations 表中的一组查询结果添加到 Users 实体中的瞬态变量中。

实体:

用户

@Entity
public class Users 
    @Id
    @GeneratedValue
    @Column(name="user_id")
    private Long userId;

    @Column(name="username", unique=true, nullable=false)
    private String username;

    @Transient
    private Set<Annotation> annotations;
    .....

注释

@Entity
@Table(name="Annotation")
public class Annotation 

    @Id
    @GeneratedValue
    @Column(name="anno_id")
    private Long annoId;

    @Column(name="user_id", nullable=false)
    private Long userId;

    @Enumerated(EnumType.STRING)
    @Column(name="access_control", nullable=false)
    private Access accessControl;

    @Column(name="group_id", nullable=true)
    private Long groupId;
    .....

所以我希望Set&lt;Annotation&gt; annotations 变量保存对 Annotations 表的查询结果。这不能简单地是一对多的映射,因为我必须以特定的方式限制结果。其实查询是这样的:

SELECT anno_id, a.user_id, timestamp, is_redacted, access_control, a.group_id, vocabulary_id, key_, value, target_type, target_id, root_type, root_id FROM Annotation AS a 
LEFT JOIN group_membership g ON g.user_id = ?# principal?.getId() 
WHERE a.user_id = :id
AND (a.access_control='PUBLIC'
OR (a.access_control='GROUP' AND a.group_id = g.group_id
OR (a.access_control='PRIVATE' AND g.user_id = a.user_id))
GROUP BY a.anno_id

我认为这可以通过 SQLResultSetMapping 实现,但是,结果似乎总是映射到另一个不同的实体。是否可以将集合提取为集合并以我想要的方式存储?

【问题讨论】:

【参考方案1】:

您不能在这种情况下使用 SQLResultSetMapping,因为结果只会被映射为不同的实体。您可以做的是作为本机查询执行,然后将结果作为对象数组列表获取。然后,您可以构造所需的对象。

        Query query = entityManager
                .createNativeQuery("SELECT anno_id, a.user_id FROM Annotation AS a"
                        + " LEFT JOIN group_membership g ON g.user_id = ?"
                        + " WHERE a.user_id = ?"
                        + " AND (a.access_control='PUBLIC'"
                        + " OR (a.access_control='GROUP' AND a.group_id = g.group_id)"
                        + " OR (a.access_control='PRIVATE' AND g.user_id = a.user_id))"
                        + " GROUP BY a.anno_id");
        query.setParameter(1, new Long(1));
        query.setParameter(2, new Long(1));
        List<Object[]> list = query.getResultList();
        return list;

【讨论】:

以上是关于如何将本机查询的结果集映射到实体中的变量的主要内容,如果未能解决你的问题,请参考以下文章

本机 SQL(用 xml 编写)结果集映射到 POJO(基于注释)

使用 JPA 2.1,我如何将本机查询结果映射到 @Transient 字段(taht is a Set)?

EclipseLink 拒绝将 PostgreSQL 上的本机查询映射到实体

Hibernate:使用@SqlResultSetMapping 映射本机查询的结果集

Mybatis结果集映射(resultMap)

如何使用 Hibernate 将 SQL 查询的结果最好地映射到非实体 Java 对象?