【问题标题】:Clear out and restore fixture data using Grails/GORM使用 Grails/GORM 清除和恢复夹具数据
【发布时间】:2015-01-24 04:06:09
【问题描述】:

我需要根据控制器请求重置 GORM 夹具数据 (H2)。所以我创建了以下控制器...

def dataSource
FixtureLoader fixtureLoader
def index() {
    Sql sql = new Sql(dataSource)
    sql.execute("DROP ALL OBJECTS DELETE FILES")
    sql.close()
    fixtureLoader.load('f1','f2','f3')
}

我希望这会清除数据库,但是,我仍然收到以下错误

[org.codehaus.groovy.grails.web.errors.GrailsExceptionResolver] 处理请求时发生 NonUniqueObjectException:[GET] 具有相同标识符值的不同对象已经存在 与会话相关联:[*]。堆栈跟踪如下: org.hibernate.NonUniqueObjectException: 一个不同的对象 相同的标识符值已与会话关联:[*]

另一个奇怪的事情是,如果我进入 dbconsole 并使用“DROP ALL OBJECTS DELETE FILES”命令将所有内容吹走,当我进入控制器时,我会遇到同样的错误。尽管我可以确认它们已从数据库中删除。

更新

所以我尝试了一些东西......

1.) 'DROP ALL OBJECTS DELETE FILES' 似乎在 dbconsole 中按预期工作。但是代码

    Sql sql = new Sql(dataSource)
    sql.execute("DROP ALL OBJECTS DELETE FILES")
    sql.close()

似乎没有同样的效果。

2.) 我添加了以下几行

def sessionFactory
...
sql.close()
sessionFactory.currentSession.flush() //This one  
fixtureLoader.load('f1','f2','f3')

然后我去数据库控制台删除(因为 SQL 似乎失败了),然后运行。但是,当我再次运行该函数时,我仍然可以看到固定装置。

【问题讨论】:

  • 听起来好像休眠会话/缓存没有被刷新/清除,因此即使您更改了数据存储也认为存在重复。您可能很幸运在测试环境中禁用了休眠缓存。
  • 这就是我认为 close 所做的,我也尝试了 sql.execute("DROP ALL OBJECTS DELETE FILES")
  • 请看我的更新,我没有正确清除缓存吗?
  • 您在这里遗漏了一个基本的难题。即使您执行一条 SQL 语句来“清除”所有数据,Hibernate 仍然存在于您的典型 Grails 应用程序中,并且默认情况下它有自己的缓存,独立于您的数据库。当您在不通过 Hibernate 的情况下更改数据库时,您正在规避 Hibernate 管理缓存的能力,因此最终会出现这种情况,虽然数据不存在,但 Hibernate 仍然认为它存在。考虑清除 Hibernate cahce,或禁用它(如果这对您的应用有意义),或使用 Hibernate 进行核对。
  • session.flush() 不会做任何事情,因为您没有使用 Hibernate 会话来影响您的数据库。所以,不,那是不正确的。

标签: grails grails-orm


【解决方案1】:

要做到这一点,我基本上和accepted answer here做的一样...

在我的 Bootstrap 中,我创建了 tmp 文件,然后当调用控制器时,我将它作为脚本运行,一切都会被重置。我还必须确保根据评论删除缓存。

【讨论】:

    猜你喜欢
    • 2021-11-27
    • 2014-10-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-12-10
    相关资源
    最近更新 更多