首页 > 解决方案 > 意外的 AST 节点:< 更新查询

问题描述

我有一个简单的 hql 查询:

"update Container container set container.obsolete = (container.maxLaunchingTime < ?2)"

但是当我尝试从会话中创建查询时,休眠会抛出异常:

Method threw 'org.hibernate.hql.internal.ast.QuerySyntaxException' exception.

unexpected AST node: < near line 1

hibernate 是否可以通过对 set 语句的操作来创建 upate 查询?

标签: javahibernate

解决方案


HQL 更新的文档如下:

UPDATE 语句的 BNF 在 HQL 和 JPQL 中是相同的:

update_statement ::=
    update_clause [where_clause]

update_clause ::=
    UPDATE entity_name [[AS] identification_variable]
    SET update_item {, update_item}*

update_item ::=
    [identification_variable.]{state_field | single_valued_object_field} = new_value

new_value ::=
    scalar_expression | simple_entity_expression | NULL

现在仍然不清楚 a scalar_expressionor到底simple_entity_expression是什么。但我担心计算表达式x < y不是两者的子集。

在您的简单示例中,您可以通过调用两个更新来解决此问题:

update Container container set container.obsolete = 1 where container.maxLaunchingTime < ?2
update Container container set container.obsolete = 0 where container.maxLaunchingTime >= ?2

由于声称 HQL UPDATE 的 BNF 与 JPQL 相同,我们可以从此处wikibooks将详细说明扩展到 JPQL BNF :

update_statement ::= update_clause [where_clause]

update_clause ::= UPDATE abstract_schema_name [[AS] identification_variable] SET update_item {, update_item}*

update_item ::= [identification_variable.]{state_field | single_valued_association_field}= new_value

new_value ::= simple_arithmetic_expression | string_primary | datetime_primary | boolean_primary | enum_primary simple_entity_expression | NULL

simple_arithmetic_expression ::= arithmetic_term | simple_arithmetic_expression {+ |- } arithmetic_term

simple_entity_expression ::= identification_variable | input_parameter

arithmetic_term ::= arithmetic_factor | arithmetic_term {* |/ } arithmetic_factor

arithmetic_factor ::= [{+ |-}] arithmetic_primary

arithmetic_primary ::= state_field_path_expression | numeric_literal | (simple_arithmetic_expression) | input_parameter | functions_returning_numerics | aggregate_expression

functions_returning_numerics ::= LENGTH(string_primary)| LOCATE(string_primary,string_primary [, simple_arithmetic_expression]) | ABS(simple_arithmetic_expression) | SQRT(simple_arithmetic_expression) | MOD(simple_arithmetic_expression, simple_arithmetic_expression) | SIZE(collection_valued_path_expression)

aggregate_expression ::= {AVG |MAX |MIN |SUM}([DISTINCT] state_field_path_expression) | COUNT ([DISTINCT] identification_variable | state_field_path_expression | single_valued_association_path_expression)

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

string_primary ::= state_field_path_expression | string_literal | input_parameter | functions_returning_strings | aggregate_expression

datetime_primary ::= state_field_path_expression | input_parameter | functions_returning_datetime | aggregate_expression

boolean_primary ::= state_field_path_expression | boolean_literal | input_parameter |

enum_primary ::= state_field_path_expression | enum_literal | input_parameter |

where_clause ::= WHERE conditional_expression
...

所以最后我们可以看到表达式 like set property = 4+5orset property = 8/2是语言的一部分,而set proeprty = 1 < 3不是。


推荐阅读