Спящие несохраненные переходные ошибки при рендеринге сложной формы с отношением «многие ко многим» - PullRequest
0 голосов
/ 13 июля 2011

Основная проблема: у меня есть отношение многие ко многим (магазины, продукты) с объектом поиска с именем ProductOffering.В ситуации, когда у меня есть постоянная StoreLocation и я пытаюсь подключить временные продукты, hibernate жалуется ДАЖЕ, ЧТО Я НЕ ХОЧУ СОХРАНИТЬ.

Вопросы:

  1. Почему grails / gorm / Hibernate пытается спасти мою сущность?
  2. Есть ли лучший способ решения этой проблемы?

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

class StoreLocation {
    String name
    List offerings
    static hasMany = [offerings:ProductOffering]
    static constraints = {
    }
}

class Product {
    String name
    static hasMany = [offeredBy:ProductOffering]
    static constraints = {
        name(unique:true)
        offeredBy(nullable:true)
    }
}

class ProductOffering {
    static belongsTo = [product:Product, store:StoreLocation]
    static constraints = {
    }
}

И мое действие "edit" StoreLocationController выглядит следующим образом.

def edit = {
    //get the store we want to edit
    def storeLocation = StoreLocation.get(params.id)
    //create a transient product and add it to the store
    // by attaching it to a transient productOffering
    def product = new Product()
    def offering = new ProductOffering()
    offering.product = product
    storeLocation.addToOfferings(offering)
    //render the edit page
    render(view:"edit", model:[storeLocation:storeLocation])
}

Предположим, у меня есть storeLocation с идентификатором= 1.Я иду, чтобы отредактировать локальный хост StoreLocation: 8080 / myapp / storeLocation / edit / 1

Не имеет значения, как выглядит мой взгляд.Это может быть <p>hello</p>

Я получаю следующую ошибку.

Ошибка 500: свойство not-null ссылается на нулевое или временное значение: ProductOffering.product;вложенным исключением является org.hibernate.PropertyValueException: свойство not-null ссылается на нулевое или временное значение: ProductOffering.product

Трассировка стека не намного полезнее:

org.springframework.dao.DataIntegrityViolationException: свойство not-null ссылается на нулевое или временное значение

1 Ответ

3 голосов
/ 13 июля 2011

Grails регистрирует перехватчик OpenSessionInView вокруг всех запросов.Это гарантирует, что сеанс Hibernate открыт в течение каждого запроса, а сеанс сбрасывается и закрывается в конце запроса.Это позволяет избежать исключений при отложенной загрузке.

Так как сеанс сбрасывается в конце запроса, любые грязные постоянные экземпляры помещаются в базу данных, и это то, что здесь происходит.Вы загружаете экземпляр storeLocation и изменяете его, чтобы изменения сбрасывались.Вам не нужно сохранять ProductOffering, поскольку он будет транзитивно сохраняться при сбросе storeLocation, а экземпляр Product - нет, поэтому вы получаете это исключение.

Простое исправлениеесли вы не хотите, чтобы какие-либо изменения были сохранены, то удалите измененный экземпляр из контекста постоянства - сделайте это, вызвав storeLocation.discard() перед вызовом рендеринга.См. http://grails.org/doc/latest/ref/Domain%20Classes/discard.html для получения информации о методе discard.

...