HQL:当其中一个字段是一对多列表时,如何查询某些字段?

时间:2017-07-11 20:40:31

标签: java hibernate hql

我在编写HQL查询时遇到困难,只能从我的caseid实体中选择titlecaseStatusCases字段。返回的案件必须基于caseid进行区分。我不希望包含nameuserid字段。我也不想对caseidtitlecaseStatus字段使用延迟提取。请注意,caseStatus字段是一对多列表。以下是实体。省略getter / setter以节省空间。

@Entity
@Table(name = "Cases")
public class Cases {
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    @Column(name = "caseid", nullable = false)
    private Integer caseid;
    private Integer userid;
    private String name;
    private String title;
    @OrderBy("caseStatusId DESC")
    @OneToMany(mappedBy = "cases", fetch = FetchType.EAGER)
    private List<CaseStatus> caseStatus;
}

@Entity
@Table(name = "CaseStatus")
public class CaseStatus {
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    @Column(name = "caseStatusId", nullable = false)
    private Integer caseStatusId;
    private String info;
    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "caseid")
    private Cases cases;
}

我的目标是检索仅包含List<Cases>List<Object[]>caseid的不同titleList<CaseStatus>个案例实体。 List<CaseStatus>将包含填充了所有字段的CaseStatus个对象。

public List<Object[]> getCases(String title) {
    TypedQuery<Object[]> q = em.createQuery("select distinct c.caseid, c.title, cs "
        + "FROM Cases c join c.caseStatus cs "
        + "where c.title like :title", Object[].class);
    q.setParameter("title", "%" + title + "%");
    List<Object[]> results = q.getResultList();
    return results;
}

上述方法很接近,但不正确,因为它不是在其中一个索引中返回List<CaseStatus>,而是只返回一个CaseStatus实体。

例如,如果我的数据库包含单个CaseList<CaseStatus>的大小为n,则结果将类似于以下示例:

我现在得到的结果示例。不正确:

        List<Object[]> index 0:
            Contains an Object[] where:
                Object[0] = {some caseid}
                Object[1] = {some title}
                Object[2] = {1st CaseStatus}
        List<Object[]> index 1:
            Contains an Object[] where:
                Object[0] = {same caseid as the one found in index 0 above}
                Object[1] = {same title as the one found in index 0 above}
                Object[2] = {2nd CaseStatus}
        ...
        List<Object[]> index n-1:
            Contains an Object[] where:
                Object[0] = {same caseid as all the previous}
                Object[1] = {same title as all the previous}
                Object[2] = {nth CaseStatus}

我希望实现的结果示例:

        List<Object[]> index 0:
            Contains an Object[] where:
                Object[0] = {unique caseid}
                Object[1] = {some title}
                Object[2] = List<CaseStatus> with size of n

更新了问题。我要检索的字段不是nametitleList<CaseStatus>,而是caseidtitleList<CaseStatus>caseid是案例的主要关键。

我找到了各种帖子Select Collections with HQL - hibernate forumSelect collections with HQL - stackoverflow。这几乎是我遇到的问题。看起来没有人在这些线程中找到解决方案。

4 个答案:

答案 0 :(得分:0)

对查询有点困惑;在HQL做你喜欢这样的加入(道歉,由于计算机问题,我在发布之前无法测试,但你应该明白这一点)

select distinct c from Cases c left join fetch c.caseStatus cs where....

&#34; fetch&#34;让它渴望。请注意,这将返回一个Case类型的数组。你在哪个条款看起来正确。

答案 1 :(得分:0)

实际上HQL是完全面向对象的并且在Query中使用了您的类结构,因此通过编写c.caseStatus HQL期望您的Cases类具有caseStatus属性,这是错误的因为它是一个集合。

如果您查看Hibernate HQL documentation,可以看到:

  

与SQL相比,HQL 完全面向对象,并且理解继承,多态和关联等概念。

我认为您需要做的是更改查询,使其与您的类结构相匹配:

    Query q = em.createQuery("select distinct c.name, c.title, cs.caseStatus FROM Cases c left join c.caseStatus where "
        + "c.name like :name and "
        + "c.title like :title");

答案 2 :(得分:0)

正确的语法应该是

TypedQuery<Object[]> q = em.createQuery("select c.name, c.title, cs FROM Cases c "
                + "join c.caseStatus cs where "
                + "c.name = :name and "
                + "c.title = :title", Object[].class);

返回类型为List<Object[]>,其中Object[]的第一个索引是c.name,第二个是c.title,第三个是关联的caseStatus实体。可以查询多个实例(行)。

我们需要JOIN,因为CaseStatus和Case之间的关系是通过集合映射的。

SELECT cs
FROM Case c JOIN c.cases cs;

答案 3 :(得分:0)

为什么不使用

MyAccount_

试试吧。这可能是一种天真的方法,但应该能够解决问题。您可能会获得比您需要的更多的字段,但返回类型将是案例列表。