我们正在使用Grails 2.2.1,当我们尝试对绑定到多个数据源的域类执行CRUD操作时会遇到问题。
这是我们的静态映射的样子和一些操作的结果:
在此方案中,CAR表仅存在于d2。
class Car {
static mapping = {
datasources(['d1','d2'])
}
}
Car.d2.listAll() //This code works and return data from d2
carObject.d2.save() //This code fails with a Table or View does not exist
现在,如果我将表格添加到d1
class Car {
static mapping = {
datasources(['d1','d2'])
}
}
Car.d2.listAll() //This code works and return data from d2
carObject.d2.save() //This code now works and inserts a row into table in d2
所以看来当你有多个数据源时,表必须存在于你列出的第一个数据源中,有没有人知道解决这个问题的方法?
更新10/27
我已尝试注入实际数据源并使用它来执行CRUD操作作为解决方法。不幸的是,grails不允许您使用注入的数据源来指定您希望更改的位置。
链接:How to use injected dataSource in Grails to perform operations?
问题似乎比最初预期的要糟糕。该表不仅必须存在于列出的第一个数据源中,而且它似乎也在检查数据。它不允许我使用d1中存在的密钥将记录插入d2。
更新2 10/27
在研究之后,似乎正在针对列出的第一个dataSource运行验证,然后正在对指定的dataSource执行实际操作。
如果我传入验证错误,它现在有效:
carObject.d2.save(validate:false)
这项工作唯一的问题显然是我失去了验证。
答案 0 :(得分:0)
我尝试为会话工厂bean创建新会话。然后执行object.save()。看起来很有效。见例:
def ctx = grailsApplication.mainContext
ctx.getBeanNamesForType(SessionFactoryImplementor.class).each {
SessionFactoryImplementor sfi = ctx.getBean(it)
GrailsSessionContext gsc = new GrailsSessionContext(sfi)
if(!TransactionSynchronizationManager.getResource(gsc.sessionFactory)) {
def newSession = gsc.sessionFactory.openSession()
def sessionHolder = new SessionHolder(newSession)
TransactionSynchronizationManager.bindResource(gsc.sessionFactory, sessionHolder)
}
}