Grails 2.5, до того, как Delelete не сможет получить доступ один-ко-многим - PullRequest
0 голосов
/ 28 февраля 2020

Использование Grails 2.5.6 здесь. Я пытаюсь получить доступ к набору строк моего класса домена в событии beforeDelete GORM. Я вижу удаление этого набора, которое выдается в журнале базы данных, прежде чем я достигну точки останова в beforeDelete.

Я получаю исключение NullPointerException для моего println (строки) ниже в классе моего домена.

Мой тестовый класс домена выглядит как

class DeleteTest {
    Integer id
    Set<String> stringSet
    String prop1
    String prop2

    static hasMany = [stringSet: String]

    static constraints = {
        prop1(maxSize: 20)
        prop2(maxSize: 20)
    }

    static mapping = {
        stringSet(joinTable: [column: 'delete_test_string_set', length: 15])
    }

    def beforeDelete() {
        withNewSession {
            Set<String> strings = this."stringSet"
            println(strings)
        }
    }
}

И я сделал такой тестовый контроллер.

class DeleteTestController {

    def create() {
        DeleteTest test = null
        DeleteTest.withTransaction {
            test = new DeleteTest(
                    prop1: 'Test',
                    prop2: 'another test',
                    stringSet: ['str1', 'str2', 'str3']
            ).save()
        }

        render (test as JSON)
    }

    def delete() {
        DeleteTest test = DeleteTest.findByProp1('Test')
        DeleteTest.withTransaction {
            test.delete()
        }

        render(test as JSON)
    }
}

Как я могу получить свой stringSet в событии beforeDelete?

1 Ответ

1 голос
/ 06 марта 2020

Одним из простых способов является загрузка stringSet перед вызовом удаления. Тем не менее, здесь явно происходят странные ситуации, и я опишу то, что нашел до сих пор.

Простой ответ

def delete() {
    DeleteTest test = DeleteTest.findByProp1('Test')
    test.stringSet?.size() // <-- force load here
    DeleteTest.withTransaction {
        test.delete()
    }
    render(test as JSON)
}

Другое Соображения

Я попытался сделать stringSet загруженным. Это не сработало, как ожидалось, и в коде beforeDelete это часто было бы одно значение или пробел.

Я также попытался сделать StringSet множеством, в котором я определил один объект GORM MyString, содержащий значение. Это сработало (хотя я должен был сделать это с нетерпением), но я не считал это правильным решением для вашего случая, поскольку я предполагаю, что у вас уже есть данные, и я не могу их просто заменить.

На основе при некотором отладочном копании я предполагаю (но на самом деле это всего лишь предположение), что коллекция удаляется до того, как сработает событие beforeDelete, и поэтому она не может быть лениво загружена в этот момент даже в новой транзакции. Я ожидаю, что кто-то еще сможет оценить, правильно это или нет, но опыт Grails 2 становится все труднее найти в наши дни.

...