まつざきの技術メモ

エンジニアの私的な技術メモです。

CDIで複数データソースの切り替え

2件のコメント

将来的にはJavaEEの仕様にマルチテナント機能が組み込まれますが、
僕は今のところ、複数データソースの切り替えが出来れば十分なので、
CDIを使ってやってみました。
これで1つのJavaEE6アプリで複数のデータベースへの接続を切り替える事が可能です。

では早速、実際のソースを見てみましょう。

 

まずはプロデューサ・メソッドから。
EntityManagerがDIされるフィードを複数持ち、プロデューサ・メソッドで何れかをreturnします。
今回の例ではシステム日付の秒で分岐しましたが、
実際はURLパラメータやCookieに保持した値などで分岐する事になると思います。
また、RequestScopedアノテーションを付けて、リクエスト毎に呼ばれるようにします。

public class EntityManagerFactory {

    @PersistenceContext(unitName = "pu01")
    private EntityManager em01;
    @PersistenceContext(unitName = "pu02")
    private EntityManager em02;

    @RequestScoped
    @Produces
    @EntityManagerQualifier
    public EntityManager getEntityManager() {
        // システム日付が偶数秒ならem01に接続する。
        DateTime dt = new DateTime();
        int sec = Integer.parseInt(dt.toString("s"));
        if (sec % 2 == 0) {
            return em01;
        } else {
            return em02;
        }
    }
}

次にDIでEntityManagerを受け取る側
DIで受け取ったEntityManagerを使うだけです。
今回の例ではコントローラに書いてます。

@Model
public class SampleController {

    @Inject
    @EntityManagerQualifier
    private EntityManager em;

    public String getName() {
        Query query = em.createNamedQuery("findAll", Sample.class);
        return ((Sample) query.getSingleResult()).getName();
    }
}

EntityManagerQualifierアノテーションはQualifier(限定子)です。
インジェクションの対象を限定(紐付け?)させています。

@Qualifier
@Retention(RUNTIME)
@Target({METHOD, FIELD, PARAMETER, TYPE})
public @interface EntityManagerQualifier {
}

ソースはGitHubにアップしてます。
READMEに環境構築の手順メモも書いてます。
サンプルソース

以上、久々のJavaネタでした!

広告

作成者: まつざき

中堅企業向けERPサービスを提供してる会社で働くソフトウェアエンジニア Perl/Ruby/Java8/Erlang/Fluentd/PostgreSQL/MySQL/Riak/Debian

CDIで複数データソースの切り替え」への2件のフィードバック

  1. こんにちは、河野です。
    これ、HttpServletRequestの内容によって処理を分岐させたい場合にどうやってHttpServletRequestオブジェクトを取得すればいいんでしょう?
    FacesContextを使う方法はあるみたいですが、JSFに依存するのはなんかイヤな感じなので・・・

コメントを残す

以下に詳細を記入するか、アイコンをクリックしてログインしてください。

WordPress.com ロゴ

WordPress.com アカウントを使ってコメントしています。 ログアウト / 変更 )

Twitter 画像

Twitter アカウントを使ってコメントしています。 ログアウト / 変更 )

Facebook の写真

Facebook アカウントを使ってコメントしています。 ログアウト / 変更 )

Google+ フォト

Google+ アカウントを使ってコメントしています。 ログアウト / 変更 )

%s と連携中