Grails编辑工作异常更新数据库值

时间:2017-11-20 05:17:36

标签: grails gorm grails-2.0 grails-domain-class grails-controller

我正在使用grails-2.1.1。当我加载编辑页面时,我在控制器的编辑操作中分配了一些值。但它正在更新我的桌子!虽然我没有储蓄。谁能帮助我如何阻止它?以下是我的代码:

我在控制器中的编辑操作>>>

def edit() {
    def accTxnMstInstance = AccTxnMst.get(params.id)
    if (!accTxnMstInstance) {
        flash.message = message(code: 'default.not.found.message', args: [message(code: 'accTxnMst.label', default: 'AccTxnMst'), params.id])
        redirect(action: "list")
        return
    }

    accTxnMstInstance?.accTxnDtls?.each {
        if (it?.debitCoa != null && it?.debitCoa != "") {
            String debitCoaVal = ""
            List<String> items = Arrays.asList(it?.debitCoa?.split("\\s*~\\s*"))
            items.each {
                List itemList = new ArrayList()
                List<String> subItems = Arrays.asList(it.split("\\^"))
                subItems.each {
                    itemList.add(it)
                }
                itemList.add("false")
                itemList.add("0")

                itemList.each {
                    debitCoaVal += it.toString() + "^"
                }
                debitCoaVal += "~"
            }

            it?.debitCoa = debitCoaVal
            debitCoaVal = ""
        }

        if (it?.creditCoa != null && it?.creditCoa != "") {
            String creditCoaVal = ""
            List<String> items = Arrays.asList(it?.creditCoa?.split("\\s*~\\s*"))
            items.each {
                List itemList = new ArrayList()
                List<String> subItems = Arrays.asList(it.split("\\^"))
                subItems.each {
                    itemList.add(it)
                }
                itemList.add("false")
                itemList.add("0")

                itemList.each {
                    creditCoaVal += it.toString() + "^"
                }
                creditCoaVal += "~"
            }

            it?.creditCoa = creditCoaVal
            creditCoaVal = ""
        }
    }

    [accTxnMstInstance: accTxnMstInstance]
}

在分配刚刚传递给视图的值后,您可以看到我没有保存。

1 个答案:

答案 0 :(得分:1)

Grails使用Open Session In View(OSIV)模式,在We​​b请求开始时打开Hibernate会话(并存储在本地线程中以便于访问),并在请求结束时只要没有异常,就会刷新并关闭Hibernate会话。在任何刷新期间,Hibernate会查看所有“活动”对象实例,并遍历每个持久属性以查看它是否“脏”。如果是这样,即使您没有明确调用save(),您的更改也会被推送到数据库。这是可能的,因为当Hibernate从数据库行创建实例时,它会缓存原始数据,以便稍后与可能更改的实例属性进行比较。

很多时候这是有用的行为,但在这样的情况下它会妨碍。虽然有很多修复。其中一个是禁用OSIV,但这通常是一个坏主意,除非你知道你在做什么。在这种情况下,您可以尝试使用两种方法。

一种是将AccTxnMst.get(params.id)更改为AccTxnMst.read(params.id)。这不会导致实例严格“只读”,因为您仍然可以显式调用save(),如果修改了某些内容,则所有实例更改都将保留。但是对于使用read()检索的实例,没有对原始数据进行缓存,并且在刷新期间没有对这些实例进行脏检查(这是不可能的,因为没有可用于比较的缓存数据)。 p>

在检索不会更新的实例(无论是否进行属性更改)时,通常使用read()是一个好主意,并使代码更加自我记录。

另一种选择是在控制器操作完成之前在实例上调用discard()。这将实例与Hibernate会话“分离”,因此当OSIV过滤器在请求结束时运行并刷新Hibernate会话时,您的实例将不会被视为脏,因为Hibernate将无法访问它。

read()仅对通过id检索的单个实例有意义,而discard()对任何实例都有用,例如如果它们在映射集合中或由非id查询检索(例如动态查找器,条件查询等)