JPA EclipseLink oracle db缺少右括号

时间:2014-07-12 14:31:24

标签: oracle jpa eclipselink

我有一个criteriaQuery:

CriteriaQuery<Employee> criteriaQuery = criteriaBuilder.createQuery(Employee.class);
Root<Employee> root = criteriaQuery.from(Employee.class);
criteriaQuery.where(criteriaBuilder.equal(root.get("type"), 1));

然后从现有查询构建rowCount查询:

   CriteriaQuery<Long> countQuery = criteriaBuilder.createQuery(Long.class);
   Root<Employee> root = criteriaQuery.from(Employee.class);
   Predicate restriction = criteriaQuery.getRestriction();
   if (restriction != null)
      countQuery.where(restriction);

   countQuery.select(criteriaBuilder.countDistinct(root));

从调试开始,

Predicate restriction = criteriaQuery.getRestriction();
从调试器看,

criteriaQuery.where是(TYPE =?)。 返回的上限不是(TYPE =?),而是((TYPE =?)=?)。

Eclipse生成SQL:

SELECT COUNT(DISTINCT(ID)) FROM EMPLOYEE WHERE ((TYPE = ?) = ?)

导致oracle 11g db出错。

 Error Code: 907
    Call: SELECT COUNT(DISTINCT(ID)) FROM EMPLOYEE WHERE ((TYPE = ?) = ?)
            bind => [1, true]
    Query: ReportQuery(referenceClass=Employee.class sql="SELECT COUNT(DISTINCT(ID)) FROM EMPLOYEE WHERE ((TYPE = ?) = ?)")
00:31:24,718 ERROR [system] ORA-00907: missing right parenthesis

java.sql.SQLSyntaxErrorException: ORA-00907: missing right parenthesis

        at oracle.jdbc.driver.T4CTTIoer.processError(T4CTTIoer.java:447)
        at oracle.jdbc.driver.T4CTTIoer.processError(T4CTTIoer.java:396)
        at oracle.jdbc.driver.T4C8Oall.processError(T4C8Oall.java:951)
        at oracle.jdbc.driver.T4CTTIfun.receive(T4CTTIfun.java:513)
        at oracle.jdbc.driver.T4CTTIfun.doRPC(T4CTTIfun.java:227)
        at oracle.jdbc.driver.T4C8Oall.doOALL(T4C8Oall.java:531)
        at oracle.jdbc.driver.T4CPreparedStatement.doOall8(T4CPreparedStatement.java:208)
        at oracle.jdbc.driver.T4CPreparedStatement.executeForDescribe(T4CPreparedStatement.java:886)
        at oracle.jdbc.driver.OracleStatement.executeMaybeDescribe(OracleStatement.java:1175)
        at oracle.jdbc.driver.OracleStatement.doExecuteWithTimeout(OracleStatement.java:1296)
        at oracle.jdbc.driver.OraclePreparedStatement.executeInternal(OraclePreparedStatement.java:3613)
        at oracle.jdbc.driver.OraclePreparedStatement.executeQuery(OraclePreparedStatement.java:3657)
        at oracle.jdbc.driver.OraclePreparedStatementWrapper.executeQuery(OraclePreparedStatementWrapper.java:1495)
        at org.eclipse.persistence.internal.databaseaccess.DatabaseAccessor.executeSelect(DatabaseAccessor.java:1007)
        at org.eclipse.persistence.internal.databaseaccess.DatabaseAccessor.basicExecuteCall(DatabaseAccessor.java:642)
        at org.eclipse.persistence.internal.databaseaccess.DatabaseAccessor.executeCall(DatabaseAccessor.java:558)
        at org.eclipse.persistence.internal.sessions.AbstractSession.basicExecuteCall(AbstractSession.java:1991)
        at org.eclipse.persistence.sessions.server.ServerSession.executeCall(ServerSession.java:570)
        at org.eclipse.persistence.internal.queries.DatasourceCallQueryMechanism.executeCall(DatasourceCallQueryMechanism.java:242)
        at org.eclipse.persistence.internal.queries.DatasourceCallQueryMechanism.executeCall(DatasourceCallQueryMechanism.java:228)
        at org.eclipse.persistence.internal.queries.DatasourceCallQueryMechanism.executeSelectCall(DatasourceCallQueryMechanism.java:299)
        at org.eclipse.persistence.internal.queries.DatasourceCallQueryMechanism.selectAllRows(DatasourceCallQueryMechanism.java:694)
        at org.eclipse.persistence.internal.queries.ExpressionQueryMechanism.selectAllRowsFromTable(ExpressionQueryMechanism.java:2738)
        at org.eclipse.persistence.internal.queries.ExpressionQueryMechanism.selectAllReportQueryRows(ExpressionQueryMechanism.java:2675)
        at org.eclipse.persistence.queries.ReportQuery.executeDatabaseQuery(ReportQuery.java:848)
        at org.eclipse.persistence.queries.DatabaseQuery.execute(DatabaseQuery.java:899)
        at org.eclipse.persistence.queries.ObjectLevelReadQuery.execute(ObjectLevelReadQuery.java:1127)
        at org.eclipse.persistence.queries.ReadAllQuery.execute(ReadAllQuery.java:403)
        at org.eclipse.persistence.queries.ObjectLevelReadQuery.executeInUnitOfWork(ObjectLevelReadQuery.java:1215)
        at org.eclipse.persistence.internal.sessions.UnitOfWorkImpl.internalExecuteQuery(UnitOfWorkImpl.java:2896)
        at org.eclipse.persistence.internal.sessions.AbstractSession.executeQuery(AbstractSession.java:1793)
        at org.eclipse.persistence.internal.sessions.AbstractSession.executeQuery(AbstractSession.java:1775)
        at org.eclipse.persistence.internal.sessions.AbstractSession.executeQuery(AbstractSession.java:1740)
        at org.eclipse.persistence.internal.jpa.QueryImpl.executeReadQuery(QueryImpl.java:258)
        at org.eclipse.persistence.internal.jpa.QueryImpl.getSingleResult(QueryImpl.java:517)
        at org.eclipse.persistence.internal.jpa.EJBQueryImpl.getSingleResult(EJBQueryImpl.java:400)

生成((TYPE =?)=?)而不是(TYPE =?)的原因是什么。

感谢您的帮助。

2 个答案:

答案 0 :(得分:0)

在不了解“TYPE”绑定的实际值的情况下,似乎绑定的实际值中的嵌入式单引号可能导致此错误。

以下网站的引言解释了这一点:ORA-00907: missing right parenthesis tips

  

如果您在其他单引号包围的短语中使用单引号,则必须使用内部单引号添加另一个单引号以避免使用ORA-00907。例如,您必须使用' '' '' '而不是' ' ' '以便ORA-00907不会被抛出语法。

*编辑1

还要考虑查看所输入参数的静态元模型表示。例如:

ParameterExpression<String> typeParam = criteriaBuilder.parameter( Integer.class );

criteriaQuery.where( criteriaBuilder.equal( root.get( Employee_.type ), typeParam ) );

其中Employee_类型是JPA规范定义的静态元模型。

以下是使用旧版EclipseLink的示例。 YMMV:

JPA 2.0 Criteria API with Maven and EclipseLink

答案 1 :(得分:0)

您不能在查询之间重复使用谓词/限制,因为它们与特定查询绑定的特定CriteriaBuilder绑定在一起。 EclipseLink允许重用构建的查询,但您必须在进行更改之前访问本机API并克隆基础EclipseLink查询。