对嵌套元素运行hql查询会返回“意外的AST节点”

时间:2019-04-02 13:19:25

标签: java grails hql gorm

当尝试使用通用的executeUpdate(query)方法更新Java对象时,grails会抛出NullPointer异常,说明:

  

意外的AST节点:。

我的对象关系的结构如下:

Class Product implements Serializable {
    String name
    Integer priority
    static belongsTo = [owner: Owner]
    static mapping = {owner fetch: 'join'}
}

Class Owner implements Serializable {
    String name
    Contract contract
    static hasMany = [product: Product]
}

Class Contract implements Serializable {
    Boolean isActive
}

我已经在数据库上成功运行了以下SQL请求:

UPDATE product SET priority = IF(
    (SELECT co.is_active FROM owner o
    JOIN contract co
    ON co.id = o.contract_id
    WHERE o.id = product.dealership_id) = 1
    , 10, 0);

但是,尝试在grails中运行以下代码会抛出NPE:

def hqlQuery = 'update Product p set p.priority = (case when p.owner.contract.isActive then 10 else 0 end)'
def result = Product.executeUpdate(hqlQuery)

那是为什么?我的类映射或HQL请求中是否缺少某些内容?

更多说明:

  • 我正在使用grails 2.3.4
  • 我在grails代码中访问信息p.owner.contract.isActive没问题
  • 产品始终具有所有者
  • 某些所有者根本没有合同(字段为空)
  • 所有者最多有1个有效合同。但是,在数据库中,几个旧合同可以引用同一所有者。

1 个答案:

答案 0 :(得分:0)

出于好奇,我在深夜设置了sample site,因为它可以正常工作

我认为这可能与事物的定义方式以及您尝试进行更新的方式有关

Product: static belongsTo = [owner: Owner]
Owner:  static hasMany = [product: Product]

这可能是问题的核心,因为您的更新是从产品开始的,或者需要更新产品,但是当它很好地影响所有者时,它可能已经拥有了许多该产品。注意到内部联接在查询中对我本地显示。

这似乎对我有用:

def hqlQuery = """update Product as p 
                  set p.priority = case when 
                  exists(select 1 from Owner o where o = p.owner and o.contract.isActive is true)
                  then 10
                  else 0
                  end 
                  where id > 0
               """
def result = Product.executeUpdate(hqlQuery)
def found = Product.findAll().priority

Might be related