Querydsl在基本聚合查询上生成无效的SQL

时间:2013-07-24 21:50:21

标签: sql-server hibernate querydsl

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

我有一个包含sessionId列的Sessions表。我想获得max 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()或其他聚合函数时,我会得到相同的行为。

2 个答案:

答案 0 :(得分:2)

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

答案 1 :(得分:1)

这里有一些问题。

  • 您使用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提供更多。