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 ) );