#grails #groovy
#grails #groovy
Вопрос:
У меня есть класс домена, который работает нормально. Но теперь я добавил Long
свойство, и оттуда все идет на юг.
Это случайное определение класса домена:
class Accident {
String fullDescription
Date dateFrom
Date dateTo
Long lastUpdated
Address address
GpsPosition gpsPosition
String providerDescription
String link
static constraints = {
address nullable: true
gpsPosition nullable: true
providerDescription nullable: true
link nullable: true
fullDescription maxSize: 1024
lastUpdated nullable: true
}
}
И вот тут я получаю ошибку:
@Transactional
class DatabaseCleanupService {
static final long timeNotUpdatedToDelete = 1 * 1000 // milliseconds
void cleanupDatabase() {
Accident accident
Accident.each {
/*ERROR AT THIS LINE*/ if (System.currentTimeMillis() - it.lastUpdated > timeNotUpdatedToDelete) {
// do stuff
}
}
}
Я могу получить доступ к свойству из других частей кода, я успешно печатаю отладочную информацию, но на данный момент она просто вылетает. Что с ним не так?
Редактировать: в сообщении об ошибке говорится следующее:
Такого свойства нет: lastUpdated
для класса: com.quarky.nehodyprahaserver.Accident
Возможные решения: последнее обновление
Комментарии:
1. Разве вам не нужно:
Accident.list().each
2. Бог. Черт возьми. Вы можете записать его 100 раз, но все равно потерпите неудачу в 101-й раз. Спасибо! Отправьте ответ, чтобы я мог его принять
3. Готово 😉 Иногда вам просто нужна вторая пара глаз 😉
Ответ №1:
Сначала вам нужно получить список аварий, изменив:
Accident.each {
Для
Accident.list().each {
Должно это исправить 🙂
Ответ №2:
В зависимости от того, сколько Accident
экземпляров имеется в вашей базе данных, вероятно, было бы значительно эффективнее выполнять фильтрацию по дате на уровне базы данных, а не каждый раз извлекать всю таблицу в Groovy objects и фильтровать post-hoc:
import groovy.time.TimeCategory
@Transactional
class DatabaseCleanupService {
static final long timeNotUpdatedToDelete = 1 * 1000 // milliseconds
void cleanupDatabase() {
use(TimeCategory) {
Accident.findAllByLastUpdatedLessThan(
timeNotUpdatedToDelete.milliseconds.ago).each {
// do stuff
}
}
}
}
(или просто встроить константу как 1.second.ago
— это выглядит неправильно, когда вы читаете ее как английское «последнее обновление менее одной секунды назад», но это правильно, поскольку LessThan
означает «раньше, чем» при применении к Date
объектам)
Комментарии:
1. tbh я не знаком с этим методом. метод
findAllByLastUpdatedLessThan
Groovy автоматически вводится (?)? Как он определяет, когда в последний раз обновлялся элемент? Сохраняет ли оно скрытое поле, установленное для каждого .save(), или я совершенно не прав? 😀2.
findAllBy...
Метод представляет собой динамический поиск , который преобразуется в SQL-запрос. ИlastUpdated
свойство автоматически поддерживается гибернацией (см. Последний абзац раздела руководства пользователя «События и автоматическая временная метка»)3. @MartinMelka … ах, извините, я вижу, что ваше
lastUpdated
свойство на самом деле не является обычным автоматически обновляемым — вам следует подумать об изменении его типа наjava.util.Date
, чтобы воспользоваться этой функцией, или назовите его как-нибудь иначе, если вы не хотите, чтобы его ошибочно приняли за автоматическую временную метку.4. Не знал о методах findAllBy . Они потрясающие! Если я правильно понимаю, простого наличия
Date lastUpdated
атрибута внутри класса домена достаточно, чтобы он автоматически заполнялся Hibernate?5. @MartinMelka да,
Date lastUpdated
свойство будет обновляться автоматически с учетом времени последнего сохранения объекта в базе данных (по любой причине, будь то явная.save()
или неявная проверка на наличие ошибок).