9

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"
    }
}
4

3 回答 3

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()

如果您确实想访问DomainClassAa 的所有实例DomainClassB,则可以为此添加一个方法:

Set getDomainClassAs() {
   DomainClassA.findAllByDomainClassBId(id)
}

但是由于您自己进行查询,因此如果您只需要一些实例,则不必加载所有实例,因此您可以执行任何您想要的查询。

于 2013-09-12T16:58:43.930 回答
0

如果有人想要更“自动化”的东西,如果适用的话,我想出了另一个解决方案,也许它会对性能产生影响,但如果你像我一样使用 MongoDB for Grails 插件,它会更容易使用,这有时会让它必须使用本机 java API 来获取文档。

What I did is that in DomainA, I use beforeValidate() to assign the value of domainClassBId and onLoad() to assign the value of dcB. This way, the flow will be more natural to what everyone is used to with Hibernate. When saving the DomainA, the will assing a DomainB to the DomainA and the onvalidate code will persist only the id to the corresponding datasource. When you load objects, for example with the DomainA.find() method, the onLoad code will make sure that the returned object has a property of type DomainB instead of an Long which you then use for quering the databse. It is basically the same approach denoted before by Burt Beckwith but in a more simple way in terms of saving and loading the DomainA. Again I'm not sure if it has performance issues, that's something I would like someone with more experience could help us with.

于 2014-06-01T17:35:44.743 回答
0

Configure your Database to create a DB-Link between two databases then you can do something like the following: Say you DB Link in database 1 pointing to database 2 is database2link then you query will look like.

select * from domain_class_A tb inner join domain_class_B@database2link tb2 on tb.domain_class_B_Id=tb2.id

And you can map DomainClassB by providing @database2link in the table name in the mapping i.e.

static mapping = {
    datasource "ds1"
    table name: "domain_class_B@database2link", schema: "schema_B"
}

Note that we are using datasource as ds1 only.

于 2019-01-25T12:53:41.293 回答