JBoss+MySQL+Eclipseでトランザクションのコンテナ管理(JDBC)

昨日は、EntityBean経由でデータベースアクセスするトランザクションをコンテナに管理してもらいましたが、今日はJDBCAPIを使ったデータベースアクセスで試してみたいと思います。
JDBCでいければ、各種JDO実装でもいけそうな気がします。
まずはSessionBeanにメソッド追加。sayHelloViaJdbcというメソッドを作りました。

/**
 * @ejb.interface-method
 *    view-type="remote" 
 **/
public String sayHelloViaJdbc(String nickName) {
    Connection con = null;
    Statement stmt = null;
    try {
        InitialContext ic = new InitialContext();
        DataSource ds = (DataSource)ic.lookup("java:/MySql-hellodb");
        con = ds.getConnection();
        stmt = con.createStatement();

        // まずHelloCountのcountを更新する
        String updateSql =
        "update hellocount set count = count + 1 where nickname = '" + nickName + "';";
        stmt.executeUpdate(updateSql);
        
        // 続いてHelloToからフルネームを取得する
        String selectSql =
        "select fullname from helloto where nickname = '" + nickName + "';";
        ResultSet rs = stmt.executeQuery(selectSql);
        String fullname = null;
        if (rs.next()) {
            fullname = rs.getString("fullname");
        }
        stmt.close();
        con.close();
        if (fullname == null) {
            throw new EJBException("no such data");
        }
        return "Hello " + fullname; 
        
    } catch (NamingException e) {
        e.printStackTrace();
        throw new EJBException(e);
    } catch (SQLException e) {
        e.printStackTrace();
        throw new EJBException(e);
    } finally {
        try {
            if (con != null) con.close();
            if (stmt != null) stmt.close();
        } catch (Exception e) {
            ;
        }
    }
}

DataSourceをJNDIから取得しています。JBossMySQLのhellodbデータベースへの接続を"java:/MySql-hellodb"というJNDI名で管理しています(何日か前の日記で設定しました)。
syaHello()メソッドと同様に、hellocountを更新してからfullnameを取得しに行き、データがなければEJBExceptionとします。

続いて、トランザクションの宣言をします。これは昨日の日記でsayHello()メソッドにRequiredと宣言したのと同様、ejb-jar.xmlにsayHelloViaJdbc()メソッドにRequiredを宣言しました。

クライアントコードは、以下のとおりです。昨日sayHello()を呼び出したのとほとんど同じです。呼び出すメソッド名が違うだけ。

        try {
            HelloWorld myBean = getHome().create();
            System.out.println("call SessionBean with parameter Bakock");
            String ret =  myBean.sayHelloViaJdbc("Bakock");
            System.out.println(ret);
        } catch (RemoteException e) {
            e.printStackTrace();
        } catch (CreateException e) {
            e.printStackTrace();
        } catch (NamingException e) {
            e.printStackTrace();
        }
        try {
            System.out.println("--------------------------------------");
            HelloWorld myBean = getHome().create();
            System.out.println("call SessionBean with parameter Bob");
            String ret =  myBean.sayHelloViaJdbc("Bob");
            System.out.println(ret);
        } catch (RemoteException e) {
            e.printStackTrace();
        } catch (CreateException e) {
            e.printStackTrace();
        } catch (NamingException e) {
            e.printStackTrace();
        }

初期データは

hellotoテーブル
                                                              • +
nickname fullname
                                                              • +
Bakock バコック ほげ太郎
John John Manjiroh
                                                              • +
hellocountテーブル
                                      • +
Bakock 4
Bob 4
                                      • +

実行結果は、コンソールが

call SessionBean with parameter Bakock
Hello バコック ほげ太郎
                                                                          • -
call SessionBean with parameter Bob java.rmi.ServerException: RemoteException occurred in server thread; nested exception is: java.rmi.ServerException: EJBException:; nested exception is: javax.ejb.EJBException: no such data ...

実行後のhellocountテーブルは

                                      • +
nickname count
                                      • +
Bakock 5
Bob 4
                                      • +

うまくいったようです。