我正在使用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()或其他聚合函数时,我会得到相同的行为。
答案 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提供更多。