GGTS Исключение нулевого указателя
Я новичок здесь, и я надеюсь, что смогу объяснить это полностью.
Работа с Grails в Action book, второе издание, с использованием Groovy Grails Tool Suite - GGTS (иначе Spring Tool Suite - STS).
GGTS релиз 3.6.4. Grails версия 2.4.4
Я все еще в Главе 1. К этому времени я добавил несколько "цитат" в свою базу данных. Когда я выполняю "println Quote.count()" через консоль Grails, я вижу, что у меня есть 4 цитаты.
Я пытаюсь запустить мой случайный GSP и получаю следующую ошибку:
Line | Method
->> 7 | doCall in C:/Users/donahujc/Documents/workspace-ggts-3.6.4.RELEASE/qotd/grails-app/views/quote/random.gsp
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Caused by NullPointerException: Cannot get property 'content' on null object**
->> 7 | doCall in C__Users_donahujc_Documents_workspace_ggts_3_6_4_RELEASE_qotd_grails_app_views_quote_random_gsp$_run_closure2_closure4
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
| 10 | run in C__Users_donahujc_Documents_workspace_ggts_3_6_4_RELEASE_qotd_grails_app_views_quote_random_gsp
| 198 | doFilter in PageFragmentCachingFilter.java
| 63 | doFilter in AbstractFilter.java
| 1142 | runWorker in java.util.concurrent.ThreadPoolExecutor
| 617 | run in java.util.concurrent.ThreadPoolExecutor$Worker
^ 745 | run . . . in java.lang.Thread
Это говорит мне о том, что мой звонок ни на что не указывает. Итак, я захожу в серверную часть DBConsole, и, конечно же, моя таблица цитат (которая содержит Content и Author) не существует.
Как это возможно, когда мой файл DataSource.groovy был изменен на следующее:
// environment specific settings
environments {
development {
dataSource {
dbCreate = "update" // one of 'create', 'create-drop', 'update', 'validate', ''
url = "jdbc:h2:devDb;MVCC=TRUE;LOCK_TIMEOUT=10000;DB_CLOSE_ON_EXIT=FALSE"
Я изменил "create-drop" на "update" и удалил ссылку на память (mem:).
Я знаю, что данные есть, потому что я могу использовать консоль Grails, чтобы запросить их.
Сложная часть в том, что я не могу пройти книгу все сразу. Поэтому мне пришлось закрывать и перезапускать GGTS несколько раз в течение нескольких дней. Я думал, что повторный запуск приложения приведет к повторной инициализации таблицы, но, похоже, это не так.
Как мне инициализировать эту таблицу? Я попытался добавить новую цитату. (Каким-то образом мой индекс перешел от цитаты № 4 к цитате № 33). Но все еще нет таблицы, из которой мой GSP мог бы извлечь.
Я просто в растерянности от того, как инициализировать эту таблицу (и данные, которые там находятся). У меня будут постоянные проблемы, потому что я буду постоянно закрывать / открывать GGTS.
Помогите
РЕДАКТИРОВАТЬ: (добавив больше моего кода)
Контроллер котировок:
def random(){
def allQuotes = Quote.list()
def randomQuote
if (allQuotes.size() > 0){
def randomIdx = new Random().nextInt(allQuotes.size())
}else {
randomQuote = new Quote(author:"Anonymous",
content:"Real Programmers double peace out on quiche")
}
[quote:randomQuote]
}
Random.gsp
<html>
<head>
<title>Random Quote</title>
</head>
<body>
<div id="quote">
<q>${quote.content}</q>
<p>${quote.author}</p>
</div>
</body>
</html>
Quote.groovy
class Quote {
String author
String content
Date created = new Date()
static constraints = {
}
}
До сих пор все работало нормально. Я знаю, что мои данные находятся в БД, потому что я могу запросить их из консоли Grails. Но консоль БД даже не показывает мою таблицу цитат:(
1 ответ
Ты будешь пинать себя, если это на самом деле код, который ты используешь:). Обратите внимание, что неинициализированным переменным в Groovy присваивается значение по умолчанию null
, Таким образом, начальное значение для randomQuote
переменная в random
действие null
,
Значение randomQuote
переменная затем присваивается quote
переменная в модели представления. Глядя на вид, я могу сказать, что NullPointerException
выбрасывается ${quote.content}
выражение. Так что если quote
является нулевым в модели, это должно означать, что randomQuote
является null
в действии.
Так что же происходит, когда в базе данных есть цитаты? Действие принимает эта ветка:
if (allQuotes.size() > 0) {
def randomIdx = new Random().nextInt(allQuotes.size())
}
Как видите, назначения для randomQuote
переменная, так что остается null
, Код из листинга 1.3 книги имеет следующий вид:
if (allQuotes.size() > 0) {
 def randomIdx = new Random().nextInt(allQuotes.size())
randomQuote = allQuotes[randomIdx]
}
Или, по крайней мере, я надеюсь, что это так. Это отображается в моей версии PDF.
Это было немного скучно, но я надеюсь, что вы можете следовать рассуждениям и использовать их для диагностики других проблем, с которыми вы сталкиваетесь. Я понимаю, что новичкам не всегда легко интерпретировать различные ошибки, с которыми они сталкиваются.