JPA EclipseLink oracle db缺少右括号

JPA EclipseLink oracle db缺少右括号,oracle,jpa,eclipselink,Oracle,Jpa,Eclipselink,我有一个标准问题: CriteriaQuery<Employee> criteriaQuery = criteriaBuilder.createQuery(Employee.class); Root<Employee> root = criteriaQuery.from(Employee.class); criteriaQuery.where(criteriaBuilder.equal(root.get("type"), 1)); criteriaQuery.where

我有一个标准问题:

CriteriaQuery<Employee> criteriaQuery = criteriaBuilder.createQuery(Employee.class);
Root<Employee> root = criteriaQuery.from(Employee.class);
criteriaQuery.where(criteriaBuilder.equal(root.get("type"), 1));
criteriaQuery.where是(类型=?),从调试器中查看。 上面返回的限制不是(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=?)的原因是什么


感谢您的帮助。

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

以下网站的引文对此进行了解释:

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

*编辑1

还可以考虑查看类型化参数的静态元模型表示。例如:

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

criteriaQuery.where( criteriaBuilder.equal( root.get( Employee_.type ), typeParam ) );
ParameterExpression typeParam=criteriaBuilder.parameter(Integer.class);
其中(criteriaBuilder.equal(root.get(Employee.type),typeParam));
其中Employee_uuType是JPA规范定义的静态元模型

下面是一个使用旧版本EclipseLink的例子。YMMV:


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

我正在Oracle 11g上使用EclipseLink 2.5.1。更新了问题,发现了问题。我还没有找到解决办法。谢谢。有没有办法把((TYPE=1)=true)去掉,变成(TYPE=1),或者防止(TYPE=1)被包装成((TYPE=1)=true)?你能发布你的员工实体吗?不确定它的注释方式是否会影响SQL的内部生成方式。请参阅上面的编辑。这是因为您能够对代码库进行这样的更改,从而利用这一点。为了回答您之前的问题,我不知道有什么方法可以去除生成的SQL片段,除非您执行类似于扩展AbstractQuery.getRestriction方法的操作,并在那里执行一些后处理。不确定这是否是最好的前进方式。尝试使用ParameterExpression处理上面的建议。我喜欢远离本机API。如果添加一个伪1=1,即(TYPE=?)和(1=1),它就可以工作。有没有办法判断一个限制是否是至少两个布尔表达式的连词(AND)?如果为false,则添加dummy(1=1)。如果不尝试执行计数查询,原始查询是否有效?原始查询有效。但是使用criteriaQuery.getRestriction()以增量方式构建查询并添加新谓词将失败。如上所述,从getRestriction返回的值不能在其他查询中重用,因为它与原始查询绑定。EclipseLink不支持它,因为当需要从新查询中克隆或重建本机表达式对象时,它会导致它们共享。谢谢。但是JPA提供了getRestriction()方法,结果应该是可用的。包装器((a=b)=true)是错误的,因为某些数据库不喜欢这种语法。
 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)
ParameterExpression<String> typeParam = criteriaBuilder.parameter( Integer.class );

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