9

belongsTo他のドメイン クラスが異なるデータソースを使用している場合、2 つのドメイン クラス間 (つまり ) を関連付けることはできますか? 2 つのデータソースは異なるデータベース ドライバーでもあります。

これは不可能かもしれないと思いますが、ここのコミュニティに連絡して、可能かどうかを確認したかったのです。今、私はそれをやろうとしていますが、通常の疑わしい 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()

DomainClassAのすべてのインスタンスにアクセスしたい場合は、DomainClassBそのためのメソッドを追加できます。

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

ただし、自分でクエリを実行しているため、一部のインスタンスのみが必要な場合でもすべてのインスタンスをロードする必要はありません。そのため、必要なクエリを実行できます。

于 2013-09-12T16:58:43.930 に答える
0

誰かがもう少し「自動化された」ものが必要な場合は、別の解決策を思いつきました。パフォーマンスに影響があるかもしれませんが、私のようにGrailsプラグイン用のMongoDBを使用している場合は、特に操作が簡単になります。ネイティブ Java API を使用してドキュメントを取得する必要があります。

私が行ったことは、DomainA で beforeValidate() を使用して domainClassBId の値を割り当て、onLoad() を使用して dcB の値を割り当てることです。このようにして、Hibernate で誰もが慣れ親しんだフローがより自然になります。DomainA を保存すると、DomainB が DomainA に割り当てられ、onvalidate コードは ID のみを対応するデータソースに保持します。たとえば DomainA.find() メソッドを使用してオブジェクトをロードすると、onLoad コードは、返されたオブジェクトに、データベースのクエリに使用する Long ではなく DomainB 型のプロパティがあることを確認します。これは、基本的に Burt Beckwith によって以前に示されたのと同じアプローチですが、DomainA の保存とロードに関してはより単純な方法です。繰り返しますが、パフォーマンスの問題があるかどうかはわかりません。それは、より経験のある人に助けてもらいたいことです.

于 2014-06-01T17:35:44.743 に答える