Как я могу отладить NPE в Grails? - PullRequest
0 голосов
/ 13 февраля 2011

Я пытаюсь выполнить сырой SQL в Grails с этим кодом:

class PlainSqlService {

    def dataSource // the Spring-Bean "dataSource" is auto-injected

    def newNum = {
        def sql = new Sql(dataSource) // Create a new instance of groovy.sql.Sql with the DB of the Grails app
        def q = "SELECT a.xaction_id, a.xdin FROM actions a WHERE a.is_approved = 0"
        def result = sql.rows(q) // Perform the query
                return result
    }
}

Но я получаю это исключение во время выполнения. Объект sql не равен нулю! Как я могу отладить его?

2011-02-13 15:55:27,507 [http-8080-1] ERROR errors.GrailsExceptionResolver  - Exception occurred when processing request: [GET] /moderator/login/index
Stacktrace follows:
java.lang.NullPointerException
    at moderator.PlainSqlService$_closure1.doCall(PlainSqlService.groovy:17)
    at moderator.PlainSqlService$_closure1.doCall(PlainSqlService.groovy)
    at moderator.LoginController$_closure1.doCall(LoginController.groovy:29)
    at moderator.LoginController$_closure1.doCall(LoginController.groovy)
    at java.lang.Thread.run(Thread.java:662)

1 Ответ

0 голосов
/ 13 февраля 2011

Трудно сказать, что происходит с ограниченным кодом, который вы предоставляете, но есть некоторые вещи, которые нужно проверить.Служба внедряется в контроллер с полем области видимости «def plainSqlService», как у вас здесь для dataSource, или вы вызываете new PlainSqlService()?Если вы создаете новый экземпляр, bean-компонент dataSource не будет внедрен, и конструктор groovy.sql.Sql не завершится с ошибкой, но запросы будут.

Одна вещь, которую нужно попробовать, - grails cleanчто-то вроде этого, которое должно работать, не работает, часто помогает полная перекомпиляция.

Один важный, но не связанный с этим момент - вы никогда не должны использовать Closures в сервисах.Контроллеры и библиотеки тегов требуют, чтобы действия и теги были реализованы с помощью Closure, но служба - это просто bean-компонент Spring, определенный в Groovy.Spring ничего не знает о Closures, и, поскольку они являются просто полем, которое Groovy выполняет, как если бы это был метод, любое проксирование, которое вы ожидаете от Spring (в частности, поведение транзакций, но также безопасность и другие функции), не произойдет, поскольку Springищет только методы.

Так что newNum должен быть объявлен как:

def newNum() {
   ...
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...