JavaEE 7 JPA 2.1の新機能ストアドプロシージャ

JPA 2.1ではついにストアドプロシージャも標準で使えるようになった。
今までは実装依存のコードで使ってはいたが。

今回もストアドを簡単にJavaのコードで作れるDerbyのストアドで。ストアドになるともう組み込みモードだと意味がないレベルだけど。

引数に文字列、戻り値に文字列を渡すストアドの設定をする。コード全部見たほうが早いと思うので一気にのせる。Derbyのoutなどは配列を使っているのが注意する点か。引数で渡して戻り値を複数返す方法ということで割り切り方としてはまぁいいのだろう。

public class DerbyEmbedded3 {
    //ストアドの実装
    public static void hello(String in1, String[] out1) {
        out1[0] = "Hello " + in1;
    }

    //main実行
    public static void main(String[] args) {

        EntityManagerFactory emf = Persistence.createEntityManagerFactory("jpatestPU3");
        EntityManager em = emf.createEntityManager();
        em.getTransaction().begin();

        //ストアドの作成
        String sql = "create procedure hello ("
                + "in in1 varchar(255) ,"
                + "out out1 varchar(255)"
                + ") "
                + " language java "
                + " parameter style java "
                + " no sql "
                + " external name 'embedded.DerbyEmbedded3.hello'";
        em.createNativeQuery(sql).executeUpdate();

        
        //ストアドの呼び出し
        StoredProcedureQuery spq = em.createStoredProcedureQuery("hello");
        spq.registerStoredProcedureParameter(1, String.class, ParameterMode.IN);
        spq.registerStoredProcedureParameter(2, String.class, ParameterMode.OUT);

        spq.setParameter(1, "world");//パラメータわたし
        spq.execute();//実行
        
        //戻り値の取得
        String result = (String) spq.getOutputParameterValue(2);
        System.out.println("result=" + result);

        em.getTransaction().rollback();

        em.close();
        emf.close();
    }
}

パラメータのIN/OUTなどをあらかじめ設定しておいて(registerStoredProcedureParameter)それに対してパラメータを設定(setParameter)する。
その後実行(execute)し、結果を(getOutputParameterValue)取り出す。


よくあるJPA2.1のストアドのサンプルはNamedQueryにしていると思う。実際ストアドを動的に作ることは少ないと思うのでこれこそNamedQuery向きではある。

でも、それじゃ面白くないので、Entityなしでコードのみで実装してみた。とはいえ上記の通りそれも難しいものではなく、非常に簡単。