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

Java HQL:当某个字段是一对多列表时,如何查询这些字段?,java,hibernate,hql,Java,Hibernate,Hql,我在编写HQL查询时遇到困难,无法从我的案例实体中仅选择案例ID、标题、和案例状态字段。返回的案例必须根据案例ID进行区分。我不希望包含名称和用户ID字段。我也不想对caseid、title和caseStatus字段使用延迟抓取。请注意,caseStatus字段是一对多列表。以下是实体。为了节省空间,省略了getter/setter @Entity @Table(name = "Cases") public class Cases { @Id @GeneratedValue(st

我在编写HQL查询时遇到困难,无法从我的
案例
实体中仅选择
案例ID
标题
、和
案例状态
字段。返回的案例必须根据案例ID进行区分。我不希望包含
名称
用户ID
字段。我也不想对
caseid
title
caseStatus
字段使用延迟抓取。请注意,
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;
}
上述方法很接近,但不正确,因为它不是在其中一个索引中返回
列表
,而是只返回单个
案例状态
实体

例如,如果my DB包含一个
案例
,其中
列表
的大小为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}
列表索引0:
包含一个对象[],其中:
对象[0]={some caseid}
对象[1]={some title}
对象[2]={1st CaseStatus}
列表索引1:
包含一个对象[],其中:
对象[0]={与上面索引0中找到的caseid相同}
对象[1]={与上面索引0中找到的标题相同}
对象[2]={2nd CaseStatus}
...
列表索引n-1:
包含一个对象[],其中:
对象[0]={与前面所有对象相同的caseid}
对象[1]={与前面所有对象的标题相同}
对象[2]={n个案例状态}
我希望取得的成果示例:

        List<Object[]> index 0:
            Contains an Object[] where:
                Object[0] = {unique caseid}
                Object[1] = {some title}
                Object[2] = List<CaseStatus> with size of n
列表索引0:
包含一个对象[],其中:
对象[0]={unique caseid}
对象[1]={some title}
对象[2]=大小为n的列表
更新了问题。我要检索的字段不是
name
title
List
,而是
caseid
title
List
<代码>案例ID是案例的主键


我发现了各种各样的线索和线索。这几乎就是我遇到的问题。看起来没有人在这些线程中找到解决方案。

休眠对查询有点困惑;在HQL中,您的加入方式是这样的(很抱歉,由于电脑不稳定,我无法在发布前进行测试,但您应该明白这一点)


“取回”使它渴望。请注意,这将返回类型case的数组。事实上,HQL是完全面向对象的,并且在查询中使用您的类结构,因此通过编写
c.caseStatus
HQL期望您的
Cases
类具有
caseStatus
属性,这是错误的,因为它是一个集合

SELECT cs
FROM Case c JOIN c.cases cs;
如果你看一下,你会发现:

然而,与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");

应该使用正确的语法

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

你为什么不直接用它呢

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

试试这个。这可能是一种幼稚的方法,但应该能够解决问题。您可能得到的字段比所需的多,但返回类型将是案例列表。

您可以发布生成的SQL查询吗?查看错误消息,它显示“由以下原因引起:com.microsoft.sqlserver.jdbc.SQLServerException:关键字“as”附近的语法不正确”。我在您的查询中没有看到任何“as”关键字,您发布了正确的查询吗?它是HQL,hibernate生成的查询是您将发现有问题的“as”的地方。如果在hibernate配置中将org.hibernate.cfg.AvailableSettings.SHOW_SQL(或“hibernate.SHOW_SQL”)设置为true,并将日志记录设置为debug,则可以看到这一点。将日志记录中生成的SQL查询添加到原始日志中。我注意到了这一点。因为col_2_0可能导致错误。我想知道为什么我写的HQL会导致这样的结果。如果你问的是关于
HQL
为什么要使用
JPA
HQL
JPA
无关,因此请从标记列表中删除
JPA
。如果您的真正意思是
JPA
查询,那么在
select
列表中使用集合值属性是非法的。我注意到,在结果列表中,每个索引都包含一个CaseStatus,而不是一个CaseStatus列表。有没有办法检索每个案例及其关联的CaseStatus列表?此外,如果案例的列表大小大于2,则返回列表不包含基于caseid的不同实体。其中将有重复的实体。您知道检索不同实体的方法吗?我尝试将关键字distinct添加到您的示例查询中,但它似乎没有影响任何内容。示例:返回类型将是List,其中Object[]的第一个索引中是c.name,第二个是c.title,第三个是associated List。一切都取决于您如何将对象保持在首位。记住,你必须始终保持关系双方的联系。你问:“我注意到在结果列表中,每个索引都包含一个CaseStatus而不是一个CaseStatus列表。”答案是:一切都取决于对象之间的关联方式(通过外键链接)。问:你知道检索不同实体的方法吗?答:请描述场景,具体需要检索什么。
SELECT cs
FROM Case c JOIN c.cases cs;
Query q = em.createQuery("select distinct c from Cases c where "
            + "c.name like :name and "
            + "c.title like :title");