基本问题:我与一个名为ProductOffering的查找实体之间存在许多关系(商店,产品)。在我有一个持久的StoreLocation并尝试附加临时产品的情况下,冬眠抱怨我什至不想保存。

问题:

  • 为什么grails / gorm / Hibernate试图保存我的实体?
  • 是否有更好的方法来解决此问题?

  • 我的域类如下所示:
    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 = {
        }
    }
    

    我的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])
    }
    

    假设我有一个ID为1的storeLocation。我去编辑StoreLocation
    本地主机:8080 / myapp / storeLocation / edit / 1

    我的看法是什么都没关系。可能是 hello
    我收到以下错误。

    错误500:not-null属性引用的是null或 transient 值:ProductOffering.product;嵌套的异常是org.hibernate.PropertyValueException:not-null属性引用的是null或 transient 值:ProductOffering.product

    堆栈跟踪没有什么用:

    org.springframework.dao.DataIntegrityViolationException:非null属性引用的是null或 transient 值

    最佳答案

    Grails围绕所有请求注册一个OpenSessionInView拦截器。这样可以确保在每个请求期间都打开一个Hibernate session ,并在请求结束时刷新并关闭该 session 。这样的好处是可以避免延迟加载异常。

    由于 session 是在请求结束时刷新的,因此所有肮脏的持久性实例都会被推送到数据库中,这就是这里发生的情况。您加载storeLocation实例并进行更改,以便刷新更改。您不需要保存ProductOffering,因为在刷新storeLocation时将以传递方式保存它,但是Product实例不是,因此您将获得此异常。

    如果您不想保留任何更改,则简单的解决方法是从持久性上下文中删除更改的实例-通过在render调用之前调用storeLocation.discard()可以做到这一点。有关discard方法的信息,请参见http://grails.org/doc/latest/ref/Domain%20Classes/discard.html

    关于hibernate - 呈现具有多对多关系的复杂表单时, hibernate 未保存的瞬时错误,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/6673332/

    10-11 00:51