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

时间:2015-04-20 17:06:17

标签: oracle jpa orm jpql

我在运行一些JPQL查询时遇到了一些问题。在我的域模型中,我有一个City类,它有一个名称和对Country对象的引用,而Country对象又有一个名称。我正在尝试运行此查询:

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)

这个问题似乎只会在我添加" country"在where子句中。也就是说,如果我做"更新城市城市SET city.name =' Americaville'在哪里city.name ='旧金山'",一切运行得很好。

我认为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

这不允许我使用深路径吗?似乎规则允许我编写entity.property1.other.more.field。

谢谢!

1 个答案:

答案 0 :(得分:0)

事实证明,JPQL在其更新子句中不允许加入。解决方法是使用where子句中的子查询来选择要更新的正确行。