Skip to content

Instantly share code, notes, and snippets.

Created April 23, 2014 23:38
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save anonymous/11236298 to your computer and use it in GitHub Desktop.
Save anonymous/11236298 to your computer and use it in GitHub Desktop.
【やりたい事】
テーブルがN個で分割されているので、テーブルのsuffixに応じて動的にdomainクラスをロードしたいです。
例.hoge_table_1, hoge_table_2 … hoge_table_9 というようにです。
domainをHogeTable_1〜HogeTable_9と作成して
Class hogeTableClass = Class.forName("path.to.HogeTable_${suffix_id}")
もしくは
def hogeTableClass = grailsApplication.getDomainClass("path.to.HogeTable_${suffix_id}).clazz
# ひとまずgrailsApplicationはcontrollerから引数で渡している
で動的にクラスをロードして
hogeTableClass.list()
などを実行したいと考えています。
# serviceに実装すると動かず、controllerに実装すると動きます。
# また、HogeUtilに実装してserviceから呼び出しても動きません。
以下の様なエラーが出ます。
*** java.lang.instrument ASSERTION FAILED ***: "!errorOutstanding" with message transform method call failed at ../../../src/share/instrument/JPLISAgent.c line: 805
【これはいやだ】
以下の様な条件分岐でdomainを実行するようなことはしたくありません。
domainに何か処理するときに毎回このコードを書くのが嫌だからです。
switch(suffix_id) {
case(1):
return HogeTable_1.list()
case(2):
return HogeTable_2.list()
}
と思い、classの部分を動的にして処理しようと言う作戦です
# 無理なら逆にlist()側を動的にして、invokeで呼び出すのもありかと書いてて思いましたが
# 同じことのような気もします。
@nobeans
Copy link

nobeans commented Apr 24, 2014

メソッドごとにswithcを用意しなくても、以下のようにドメインクラスのファクトリ風にまとめれば、ドメインクラスのバリエーションが追加されない限り大丈夫かと。(以前にこの方法で実装したことがあります)

Class classOf(int suffix_id) {
    switch(suffix_id) {
      case(1):
        return HogeTable_1
      case(2):
        return HogeTable_2
      default:
        throw new XxxException("Invalid suffix_id: %suffix_id")
    }
}

@oshiro-kazuma
Copy link

うまくいきました。ありがとうございます。
(はじめ自分が試していたgrails projectだとうまく動かなかったのですが、新しく作るとうまく動きました。
(もしかするとクラスローダが上手く動かないのも、私のコードの他の箇所に原因があるのかもしれませんが、仰っていたようにドメインクラスなどはアーティファクトとしてGrails側で特殊処理施されていると思うのでこちらの方法を使用します。

Hoge domain class

package test

class Hoge {

    int id
    String title
    String text

    static constraints = {
    }

    static Class classOf(int suffix_id) {
        switch (suffix_id) {
            case 1:
                return Hoge_1
            case 2:
                return Hoge_2
            case 3:
                return Hoge_3
            default:
                throw new IllegalArgumentException("Invalid suffix_id: %suffix_id")
        }
    }
}

Hoge_1 domain class

package test

class Hoge_1 extends Hoge {
    static constraints = {
    }
}

HogeService class

package test

import grails.transaction.Transactional

@Transactional
class HogeService {

    def getList(int suffix_id) {
        Hoge.classOf(suffix_id).list()
    }

}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment