Oracle 抛出奇怪错误的 JPQL 更新查询。我该如何解决?

JPQL update query with Oracle throwing odd error. How can I fix it?

我在一些 JPQL 查询中遇到了一些问题 运行。在我的领域模型中,我有一个城市 class,它有一个名称和一个对国家对象的引用,而国家对象也有一个名称。我正在尝试 运行 这个查询:

Query q = em.createQuery("UPDATE City city SET city.name = 'Americaville' WHERE city.country.name = 'America'");
q.executeUpdate();

但是,我遇到了这个异常:

 java.sql.SQLSyntaxErrorException: ORA-00971: missing SET keyword

    at oracle.jdbc.driver.T4CTTIoer.processError(T4CTTIoer.java:445)
    at oracle.jdbc.driver.T4CTTIoer.processError(T4CTTIoer.java:396)
    at oracle.jdbc.driver.T4C8Oall.processError(T4C8Oall.java:879)
    at oracle.jdbc.driver.T4CTTIfun.receive(T4CTTIfun.java:450)
    at oracle.jdbc.driver.T4CTTIfun.doRPC(T4CTTIfun.java:192)
    at oracle.jdbc.driver.T4C8Oall.doOALL(T4C8Oall.java:531)
    at oracle.jdbc.driver.T4CPreparedStatement.doOall8(T4CPreparedStatement.java:207)
    at oracle.jdbc.driver.T4CPreparedStatement.executeForRows(T4CPreparedStatement.java:1044)
    at oracle.jdbc.driver.OracleStatement.doExecuteWithTimeout(OracleStatement.java:1329)
    at oracle.jdbc.driver.OraclePreparedStatement.executeInternal(OraclePreparedStatement.java:3584)
    at oracle.jdbc.driver.OraclePreparedStatement.executeUpdate(OraclePreparedStatement.java:3665)
    at oracle.jdbc.driver.OraclePreparedStatementWrapper.executeUpdate(OraclePreparedStatementWrapper.java:1352)
    at org.hibernate.engine.jdbc.internal.ResultSetReturnImpl.executeUpdate(ResultSetReturnImpl.java:208)

这个问题似乎只有在我在 where 子句中添加 "country" 时才会出现。也就是说,如果我这样做 "UPDATE City city SET city.name = 'Americaville' WHERE city.name = 'San Francisco'",一切 运行 都很好。

我认为 JPQL 可能不允许深度 属性 遍历,但查看 JPQL 规范 (http://docs.oracle.com/cd/E12839_01/apirefs.1111/e13946/ejb3_langref.html#ejb3_langref_bulk_ops),我明白了

single_valued_association_path_expression ::= identification_variable.{single_valued_association_field.}*single_valued_association_field

这不允许我使用深层路径吗?这似乎是一条允许我写实体的规则。property1.other.more.field .

谢谢!

事实证明,JPQL 不允许在其更新子句中进行联接。解决方法是在 where 子句中使用子查询 select 要更新的正确行。