Выполнение hql-запроса для вложенного элемента возвращает «неожиданный узел AST» - PullRequest
1 голос
/ 02 апреля 2019

При попытке обновить мой java-объект с использованием универсального метода executeUpdate(query), 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
  • У меня нетпроблема с доступом к информации p.owner.contract.isActive в моем коде Grails
  • У продукта всегда есть владелец
  • У некоторых владельцев нет договоров вообще (поле имеет значение null)
  • Anвладелец имеет не более 1 активного контракта.Однако в базе данных несколько старых контрактов могут ссылаться на одного и того же владельца.

1 Ответ

0 голосов
/ 03 апреля 2019

Я настроил образец сайта прошлой ночью из любопытства, потому что он должен работать

Я думаю, что, возможно, к тому, как вещи определены и как вы пытаетесь обновить:

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

Может быть связано

...