【问题标题】:Querydsl generates invalid SQL on basic aggregate queryQuerydsl 在基本聚合查询上生成无效 SQL
【发布时间】:2013-07-24 21:50:21
【问题描述】:

我正在使用 QueryDSL 和 Hibernate 来查询 SqlServer2008 数据库。

我有一个包含 sessionId 列的 Sessions 表。我想获取最大的 sessionId。

我运行以下查询:

QSessions session = QSessions.sessions;
HibernateSQLQuery query = new HibernateSQLQuery(sessionFactory.openSession(), new SQLServer2005Templates());
query.from(session).list(session.sessionId.max());

我的hibernate.cfg.xml:

<hibernate-configuration>
    <session-factory>
        <property name="hibernate.connection.url">jdbc:sqlserver://SVR;databaseName=DB</property>
        <property name="hibernate.connection.username">X</property>
        <property name="hibernate.connection.password">X</property>
        <property name="hibernate.connection.driver_class">com.microsoft.sqlserver.jdbc.SQLServerDriver</property>
        <property name="hibernate.dialect">org.hibernate.dialect.SQLServer2008Dialect</property>

        <mapping class="com.coveo.data.Sessions" />
    </session-factory>
</hibernate-configuration>

当我运行查询时,我可以看到 Hibernate 尝试运行以下 SQL 查询:

17:36:10.011 [main] DEBUG org.hibernate.SQL - select max(sessions.*.sessionId) as col__1 from sessions

这不是有效的 SQL。我早就料到了

select max(sessions.sessionId) as col__1 from sessions

当 Hibernate 尝试执行查询时,我收到以下错误:

com.microsoft.sqlserver.jdbc.SQLServerException: Incorrect syntax near '*'.

我在尝试使用 SQL Management Studio 运行无效的 SQL 查询时遇到相同的语法错误。

为什么 Querydsl 需要方言?不是Hibernate负责生成SQL吗?

为什么生成的 SQL 无效?

编辑:使用 .avg()、.min() 或其他聚合函数时,我得到相同的行为。

【问题讨论】:

  • 你和querydsl support / forums等谈过了吗?我不确定这里有多少人熟悉 querydsl,没关系能告诉你为什么它会这样工作。
  • @AaronBertrand:我猜至少有 21 个。
  • @AndriyM 我想我没有清楚地表达我的观点。没想到数字是0,但是现在有多少在线,看标签等等?我将从支持论坛开始。
  • 我听从了你的建议。

标签: sql-server hibernate querydsl


【解决方案1】:

我最终切换到jOOQ。 到目前为止,经验非常积极。 API 有点类似,文档更好,不会生成无效的 SQL。

【讨论】:

    【解决方案2】:

    这里有几个问题。

    • 您使用HibernateSQLQuery 是为了通过Hibernate API 执行SQL 查询,请使用HibernateQuery 进行Hibernate ORM 查询

    • 您在 SQL 查询中使用为 ORM 查询生成的 Q 类型。 Querydsl 应该更好地处理这种用法,我为它创建了一张票 https://github.com/mysema/querydsl/issues/463

    Querydsl 支持基于 ORM 和 SQL 的 Hibernate 查询,但您不小心将它们混合在一起。

    对于普通的 Hibernate 查询,您的示例将是

    QSessions session = QSessions.sessions;
    HibernateQuery query = new HibernateQuery(sessionFactory.openSession());
    query.from(session).list(session.sessionId.max());
    

    我假设 QSessions 是基于 Sessions 实体的。

    jOOQ 是 SQL 级别的一个很好的替代方案,但如果您还需要访问基于 JPA 和 NoSQL 的存储,Querydsl 提供了更多。

    【讨论】:

      猜你喜欢
      • 2014-11-24
      • 2013-05-11
      • 2019-01-04
      • 1970-01-01
      • 2022-01-22
      • 1970-01-01
      • 2019-05-31
      • 1970-01-01
      • 2017-10-01
      相关资源
      最近更新 更多