简体   繁体   English

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

[英]HQL: How to query certain fields when one of those fields is a one-to-many List?

I am having difficulty writing a HQL query to select ONLY the caseid , title , and caseStatus fields from my Cases entity. 我在编写HQL查询以caseStatus Cases实体中选择caseidtitlecaseStatus字段时遇到困难。 The cases returned have to be distinct based on caseid. 返回的案例必须根据caseid是不同的。 I do not want the name and userid fields to be included. 我不希望包含nameuserid字段。 I also do not want to use Lazy fetching for caseid , title , and caseStatus fields. 我也不想对caseidtitlecaseStatus字段使用惰性抓取。 Note that the caseStatus field is a one-to-many List. 请注意, caseStatus字段是一对多列表。 Below are the entities. 以下是实体。 The getters/setters are omitted to save space. 为了节省空间,省略了吸气剂/吸气剂。

@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;
}

My goal is to retrieve a distinct List<Cases> or List<Object[]> of the Cases entity containing only caseid , title , and a List<CaseStatus> . 我的目标是检索仅包含caseidtitleList<CaseStatus>的Cases实体的不同List<Cases>List<Object[]> List<CaseStatus> The List<CaseStatus> will contain CaseStatus objects with all of its fields populated. 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;
}

The above method is close, but not correct because rather than returning a List<CaseStatus> in one of the indexes, it is only returning a single CaseStatus entity. 上面的方法很接近,但是不正确,因为它只返回一个CaseStatus实体,而不是在其中一个索引中返回List<CaseStatus>

For example, if my DB contains a single Case with a List<CaseStatus> having a size of n for example, the results will be similar to the example below: 例如,如果我的数据库包含一个大小为n的List<CaseStatus>的单个Case ,则结果将类似于以下示例:

Example of results I'm getting now. 我现在得到的结果示例。 Not correct: 不正确:

        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}

Example of results I hope to achieve: 我希望达到的结果示例:

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

Updated the question. 更新了问题。 Instead of name , title , and List<CaseStatus> , the fields I want to retrieve are caseid , title , and List<CaseStatus> . 取而代之的nametitleList<CaseStatus>我要检索的字段caseidtitleList<CaseStatus> caseid is the primary key of Cases. caseid是Cases的主键。

I found various threads Select Collections with HQL - hibernate forum and Select collections with HQL - stackoverflow . 我在HQL-hibernate论坛中找到了多个线程Select Collections, 在HQL-stackoverflow中找到了Select Collections It's pretty much the problem I ran into. 这几乎是我遇到的问题。 Looks like no one found a solution in these threads. 似乎没人在这些线程中找到解决方案。

Hibernates a bit confused about the query; 休眠使查询有些混乱; in HQL do your join like this (apologies, I've not been able to test before posting due to wonky computer, but you should get the idea) 在HQL中进行这样的加入(不好意思,由于计算机运行缓慢,我无法在发布前进行测试,但您应该有个主意)

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

the "fetch" makes it eager. “获取”使它渴望。 Note that this will return an array of type Cases. 请注意,这将返回Cases类型的数组。 You where clauses look about right. 您的where子句看起来正确。

In fact HQL is fully object-oriented and uses your classes structure in the Query, so by writing c.caseStatus HQL expects that your Cases class has a caseStatus property, which is wrong because it's a collection. 实际上,HQL是完全面向对象的,并在查询中使用您的类结构,因此通过编写c.caseStatus HQL希望您的Cases类具有caseStatus属性,这是错误的,因为它是一个集合。

If you take a look at Hibernate HQL documentation you can see that: 如果查看Hibernate HQL文档,您会看到:

Compared with SQL, however, HQL is fully object-oriented and understands notions like inheritance, polymorphism and association. 但是,与SQL相比,HQL 完全面向对象,并且了解诸如继承,多态性和关联之类的概念。

I think what you need to do here is to change your query so it matches your classes structures: 我认为您需要在此处更改查询,使其与您的类结构匹配:

    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");

Correct syntax should be 正确的语法应该是

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);

Return type will be List<Object[]> , where in first index of Object[] is c.name, second is c.title and third is associated caseStatus entity. 返回类型将是List<Object[]>其中,在第一索引Object[]是c.name,第二是c.title和第三关联caseStatus实体。 It is possible to query for multiple instances (rows). 可以查询多个实例(行)。

We need JOIN because relationship between CaseStatus and Case is mapped via collection. 我们需要JOIN,因为CaseStatus和Case之间的关系是通过集合映射的。

SELECT cs
FROM Case c JOIN c.cases cs;

Why don't you just use 你为什么不只用

Query q = em.createQuery("select distinct c from Cases c where "
            + "c.name like :name and "
            + "c.title like :title");

Just try this. 尝试一下。 This may be a naive approach but should be able to solve the problem. 这可能是幼稚的方法,但应该能够解决问题。 You may be getting more fields than you required but the return type would be list of Cases. 您可能获得的字段超出了您的要求,但返回类型将是“案例”列表。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM