You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

SpringBoot+Hibernate 6.1.7.Final中SQL转HQL时出现语义异常的问题求助

SpringBoot+Hibernate 6.1.7.Final中SQL转HQL时出现语义异常的问题求助

我正在运行一个基于SpringBoot的Java应用,目前使用的是hibernate-core 6.1.7.Final版本。我有一段能正常返回预期结果的SQL查询语句,需要把它转换成HQL,这样我的应用就能执行该查询并得到相同的结果。但应用启动时总是报错,在尝试修正HQL的过程中遇到过好几种不同的错误,当前代码对应的错误是:

java.lang.IllegalArgumentException: Component at index 0 has no alias, but alias is required

能正常工作的SQL查询语句

这段SQL可以正确返回我需要的结果:

SELECT PARENT.*
, CHILD1.*
FROM [dbo].[PARENT] PARENT
INNER JOIN [dbo].[CHILD] CHILD1
ON CHILD1.ParentId = PARENT.id
INNER JOIN (
SELECT parentId, MAX(effectivetimestamp) as MaxEff, Max([createdtimestamp]) as MaxCre
FROM [dbo].[CHILD] as CHILD2
WHERE CHILD2.effectivetimestamp < Cast(Getutcdate() at time zone 'UTC' at time zone 'GMT Standard Time' AS DATETIME2)
GROUP BY parentId
) CHILD2
ON CHILD2.parentId = CHILD1.parentId
AND CHILD2.MaxEff = CHILD1.effectiveTimestamp
AND CHILD2.MaxCre = CHILD1.createdTimestamp

实体关系说明

dbo.PARENT和dbo.CHILD是一对多的关联关系,dbo.CHILD包含effectiveTimestamp字段,上述SQL的作用是返回所有Parent对象,同时关联每个Parent当前有效的Child(即每个Parent对应的effectiveTimestamp最新且不是未来日期的Child)。

对应的Java实体类

Parent类

@Entity
@Table(name = "PARENT")
public class Parent {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "id", nullable = false, unique = true)
    private Integer id;

    @OneToMany(mappedBy = "parent", fetch = FetchType.EAGER, cascade = CascadeType.ALL, orphanRemoval = true)
    @Fetch(value = FetchMode.SUBSELECT)
    @JsonManagedReference
    private List<Child> child;

    public List<Child> getChild() {
        return child;
    }

    public void setChild(List<Child> child) {
        this.child = child;
    }
}

Child类

@Entity
@Table(name = "CHILD")
public class Child {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "id", nullable = false, unique = true)
    private Integer id;

    @ManyToOne
    @JoinColumn(name = "parentId")
    @JsonBackReference
    private Parent parent;

    @Column(name = "effectiveTimestamp", nullable = false)
    private LocalDateTime effectiveTimestamp;

    @Column(name = "createdTimestamp", nullable = false)
    private LocalDateTime createdTimestamp;

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public Parent getParent() {
        return parent;
    }

    public void setParent(Parent parent) {
        this.parent = parent;
    }

    public LocalDateTime getEffectiveTimestamp() {
        return effectiveTimestamp;
    }

    public void setEffectiveTimestamp(LocalDateTime effectiveTimestamp) {
        this.effectiveTimestamp = effectiveTimestamp;
    }

    public LocalDateTime getCreatedTimestamp() {
        return createdTimestamp;
    }

    public void setCreatedTimestamp(LocalDateTime createdTimestamp) {
        this.createdTimestamp = createdTimestamp;
    }
}

我尝试的HQL查询(初始版本)

我想让这个查询返回表中所有Parent对象,并且只关联每个Parent当前有效的Child,但这段代码启动时报错:

@Query(value = "SELECT PARENT, CHILD1 FROM Parent PARENT "
        + " INNER JOIN Child CHILD1 "
        + "   ON CHILD1.parent.id = PARENT.id "
        + "   INNER JOIN "
        + "  ( SELECT CHILD1.parent.id, MAX(CHILD1.effectiveTimestamp) as MaxEff, MAX(CHILD1.createdTimestamp) as MaxCre "
        + "  FROM Child as CHILD2 "
        + "     WHERE CHILD1.effectiveTimestamp <= :currentTimestamp "
        + "     GROUP BY CHILD1.parent.id "
        + "     ) CHILD2 "
        + "   ON CHILD2.parent.id = CHILD1.parent.id "
        + "   AND CHILD2.MaxEff = CHILD1.effectiveTimestamp "
        + "   AND CHILD2.MaxCre = CHILD1.createdTimestamp " )
Optional<List<Parent>> getAllActiveChildByParent(@Param("currentTimestamp") LocalDateTime currentTimestamp);

更新后的尝试及新错误

根据Andrey B. Panfilov的建议,我给子查询中的字段添加了别名,修改后的代码如下:

@Query(value = "SELECT PARENT, CHILD1 FROM Parent PARENT "
        + " INNER JOIN Child CHILD1 "
        + "   ON CHILD1.parent.id = PARENT.id "
        + "   INNER JOIN "
        + "  ( SELECT CHILD1.parent.id as NEWALIAS, MAX(CHILD1.effectiveTimestamp) as MaxEff, MAX(CHILD1.createdTimestamp) as MaxCre "
        + "  FROM Child as CHILD2 "
        + "     WHERE CHILD1.effectiveTimestamp <= :currentTimestamp "
        + "     GROUP BY CHILD1.parent.id "
        + "     ) CHILD2 "
        + "   ON CHILD2.parent.id = CHILD1.parent.id "
        + "   AND CHILD2.MaxEff = CHILD1.effectiveTimestamp "
        + "   AND CHILD2.MaxCre = CHILD1.createdTimestamp " )
Optional<List<Parent>> getAllActiveChildByParent(@Param("currentTimestamp") LocalDateTime currentTimestamp);

但现在又出现了新的错误:

Caused by: org.hibernate.query.SemanticException: Could not resolve attribute 'parent' of 'java.lang.Object[]'

我排查后觉得问题应该出在第二个内连接的部分,但实在找不到具体哪里有问题,希望能得到大家的帮助!

备注:内容来源于stack exchange,提问作者kuytsce

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.22 13:33:03