我试图使用JPA做一个简单的选择:
SELECT POW(2, 10) FROM COUNTRY
所以,我试一试:
EntityManager em = getEM();
CriteriaBuilder cb = em.getCriteriaBuilder( );
CriteriaQuery< Object > cq = cb.createQuery( );
cq.from( Country.class );
cq.multiselect( cb.function( "POW", Integer.class, cb.literal( 2 ), cb.literal( 10 ) ) );
em.createQuery( cq ).getResultList( );
这给了我一个QueryException
:
java.lang.IllegalArgumentException: org.hibernate.QueryException: No data type for node: org.hibernate.hql.internal.ast.tree.MethodNode
\-[METHOD_CALL] MethodNode: 'function (POW)'
+-[METHOD_NAME] IdentNode: 'POW' {originalText=POW}
\-[EXPR_LIST] SqlNode: 'exprList'
+-[NUM_INT] LiteralNode: '2'
\-[NUM_INT] LiteralNode: '10'
[select function('POW', 2, 10) from model.Country as generatedAlias0]
然后,我试图施展它:
EntityManager em = getEM();
CriteriaBuilder cb = em.getCriteriaBuilder( );
CriteriaQuery< Object > cq = cb.createQuery( );
cq.from( Country.class );
cq.multiselect( cb.function( "POW", Integer.class, cb.literal( 2 ), cb.literal( 10 ) ).as( Long.class ) );
em.createQuery( cq ).getResultList( );
(我试图将其转换为String和Long。转换为Integer导致与上面相同的异常。)
然后我得到另一个QueryException:
java.lang.IllegalArgumentException: org.hibernate.QueryException: CAST function should only have 2 arguments [select cast(function('POW', 2, 10) as string) from model.Country as generatedAlias0]
[...]
at org.hibernate.internal.AbstractSharedSessionContract.createQuery(AbstractSharedSessionContract.java:655)
... 31 more
Caused by: org.hibernate.QueryException: CAST function should only have 2 arguments
at org.hibernate.hql.internal.ast.SqlGenerator$CastFunctionArguments.betweenFunctionArguments(SqlGenerator.java:300)
at org.hibernate.hql.internal.ast.SqlGenerator.betweenFunctionArguments(SqlGenerator.java:137)
at org.hibernate.hql.internal.antlr.SqlGeneratorBase.methodCall(SqlGeneratorBase.java:2584)
at org.hibernate.hql.internal.antlr.SqlGeneratorBase.selectExpr(SqlGeneratorBase.java:2130)
at org.hibernate.hql.internal.antlr.SqlGeneratorBase.selectColumn(SqlGeneratorBase.java:1942)
at org.hibernate.hql.internal.antlr.SqlGeneratorBase.selectClause(SqlGeneratorBase.java:555)
at org.hibernate.hql.internal.antlr.SqlGeneratorBase.selectStatement(SqlGeneratorBase.java:197)
at org.hibernate.hql.internal.antlr.SqlGeneratorBase.statement(SqlGeneratorBase.java:146)
at org.hibernate.hql.internal.ast.QueryTranslatorImpl.generate(QueryTranslatorImpl.java:248)
at org.hibernate.hql.internal.ast.QueryTranslatorImpl.doCompile(QueryTranslatorImpl.java:209)
... 37 more
我做错了什么?
P.S。:我用EclipseLink尝试了上面的查询,它运行正常。
答案 0 :(得分:0)
正如Hibernate组织成员所述,此问题将在版本6.0 +上解决。
但是他表示可以解决这个问题。如果您遇到此问题,则需要在Dialect级别声明该函数:
// Extends on the best dialect for your case
public class NewDialect extends MySQLDialect {
public NewDialect( ) {
registerFunction( "POW", new StandardSQLFunction( "POW", StandardBasicTypes.DOUBLE ) );
}
}
// In your hibernate config: (assuming you are using StandardServiceRegistryBuilder)
ssrb.applySetting( "hibernate.dialect", "com.example.NewDialect" );