如果另一个域类使用不同的数据源,是否可以在两个域类(即belongsTo
)之间建立关联?这两个数据源也是不同的数据库驱动程序。
我怀疑这可能不可行,但我想在这里与社区联系,看看是否有可能。现在我正在尝试这样做,我得到了通常怀疑的Hibernate错误:
Invocation of init method failed; nested exception is org.hibernate.MappingException: An association from the table domain_class_A refers to an unmapped class: DomainClassB
样品:
class DomainClassA {
static belongsTo = [dcB: DomainClassB]
static mapping = {
datasource "ds1"
table name: "domain_class_A", schema: "schema_A"
}
}
class DomainClassB {
static hasMany = [dcA: DomainClassA]
static mapping = {
datasource "ds2"
table name: "domain_class_B", schema: "schema_B"
}
}
答案 0 :(得分:8)
正如@dmahapatro在他的评论中指出的那样,这与1元素的情况类似,并且创建自己的方法来管理关系是要走的路。这也与我之前关于映射集合的性能问题的讨论有关,所以你可以一石二鸟:http://www.infoq.com/presentations/GORM-Performance
如果您不需要集合,即如果您只使用它来添加子对象的新实例,那么这将起作用,因为get
实例的DomainClassB
调用将使用它数据源:
class DomainClassA {
Long domainClassBId
private DomainClassB dcB
DomainClassB getDomainClassB() {
if (!dcB && domainClassBId) {
dcB = DomainClassB.get(domainClassBId)
}
dcB
}
void setDomainClassB(DomainClassB dc) {
domainClassBId = dc.id
}
static transients = ['domainClassB']
static mapping = {
datasource "ds1"
table name: "domain_class_A", schema: "schema_A"
}
}
class DomainClassB {
static mapping = {
datasource "ds2"
table name: "domain_class_B", schema: "schema_B"
}
}
创建一个新的DomainClassA实例与传统的addTo...
方法略有不同,但它并不太糟糕:
DomainClassB dcb = ...
def dca = new DomainClassA(domainClassBId: dcb.id)
dca.save()
如果您确实想要访问DomainClassA
的所有DomainClassB
个实例,可以为此添加方法:
Set getDomainClassAs() {
DomainClassA.findAllByDomainClassBId(id)
}
但是,由于您自己正在进行查询,因此如果只需要一些实例,则无需加载所有实例,因此您可以执行任何所需的查询。
答案 1 :(得分:0)
我想出了另一个解决方案,如果有人想要一些更“自动化”的东西,如果适用的话,也许它有性能的重复,但如果你像我一样使用MongoDB for Grails插件,它会更容易使用有时候需要使用本机java API来获取文档。
我所做的是在DomainA中,我使用beforeValidate()来分配domainClassBId和onLoad()的值来分配dcB的值。这样,流程对于每个人习惯使用Hibernate都会更自然。保存DomainA时,将DomainB分配给DomainA和onvalidate代码将仅将id保留到相应的数据源。当您加载对象时,例如使用DomainA.find()方法,onLoad代码将确保返回的对象具有DomainB类型的属性而不是Long,然后您可以使用它来查询数据库。它基本上与Burt Beckwith之前表示的方法相同,但在保存和加载DomainA方面更简单。我不确定它是否存在性能问题,我希望有更多经验的人可以帮助我们。
答案 2 :(得分:0)
配置数据库以在两个数据库之间创建DB-Link,然后可以执行以下操作:假设数据库1中的DB Link指向数据库2为database2link,则查询将类似。
从domain_class_A tb内部联接中选择* * tb.domain_class_B_Id = tb2.id上的domain_class_B @ database2link tb2
您可以通过在映射表名称中提供@ database2link来映射DomainClassB,即
static mapping = {
datasource "ds1"
table name: "domain_class_B@database2link", schema: "schema_B"
}
请注意,我们仅将数据源用作ds1。