JBoss AS 7からOracle 11gに繋いでJPAを試したかったので。
2012/10/28 追記 ここから
6.0 以前は設定ファイルを直接編集する方法がメインでしたが、7 以降は管理コンソールを使う方が標準的な方法になるようです。
JBoss AS 7.1.0 でのデータソース定義(DB2 for i) - i am BEST - livedoor Wiki(ウィキ) より抜粋
とか書いてる人がいる。なので、AS 7へのデータソース追加は、自分のこのエントリで書いてるような直接XMLを編集するのは古いやり方に属するかも。
2012/10/28 追記 ここまで
こんな環境でやりました
なお、このエントリを書くにあたってはJava @ Work: Oracle / PostgreSQL Datasource in JBoss AS 7を参考にしています。
やったこと
まずJBoss Toolsプラグイン入れるともれなく下図のようなJBoss CentralとかいうJBossのポータルのようなものを表示するビューも同梱されてくる。Create Projects -> Java EE Web Projectを選択すると雛形を作ってくれるので、このエントリではコレを利用する。なお、スクリーンショットのDescriptionにもあるとおり、ここからプロジェクトを作るにはJBoss AS 7とMaven 3(というかm2eプラグイン)は先に使える状態にしておく必要がある。
というわけでプロジェクト作ると、Java EEプロジェクト作られてMavenに沿ったディレクトリ構成作られてJPA用のpersistence.xml作られてと、ひとまずの準備はコレで完了。
次に、データソースであるOracleに接続できるような設定をしていくわけだけど、大きく2種類の作業が必要。一つはデプロイつーかJPA用のpersistence.xmlに書くデータソースの書き換えで、これはJPAとして汎用的な記述。もう一つはJBossからOracleへのデータソース接続の設定で、こちらはJBoss AS 7に固有の設定を書く必要がある。
persistence.xmlの修正
src/main/resources/META-INF/persistence.xmlを下記のように修正する。データソース名とかがサンプルのままなのでその辺は適宜読み替えで。
<?xml version="1.0" encoding="UTF-8"?> <persistence version="2.0" xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation=" http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd"> <persistence-unit name="database"> <jta-data-source>java:jboss/datasources/ExampleDS</jta-data-source> <properties> <property name="hibernate.show_sql" value="true" /> </properties> </persistence-unit> </persistence>
JBossのModuleの追加
詳しいことは俺自身よくわかってないので省略してしまうが、兎に角JBoss AS 7ではデータソースの設定はJBoss ASのModuleとして登録する必要がある。
まず%JBOSS_HOME%/standalone/configuration/standalone.xmlを下記のように編集する。persistence.xmlのデータソース名とここのjndi-nameが一致してれば一先ずはOK.
<subsystem xmlns="urn:jboss:domain:datasources:1.0"> <datasources> <datasource jndi-name="java:jboss/datasources/ExampleDS" pool-name="ExampleDS" enabled="true" use-java-context="true"> <connection-url>jdbc:oracle:thin:@localhost:1521:XE</connection-url> <security> <user-name>kagamihoge</user-name> <password>xxxxxxxxxx</password> </security> <driver>oracle</driver> </datasource> <drivers> <driver name="oracle" module="com.oracle.db"> <datasource-class>oracle.jdbc.OracleDriver</datasource-class> </driver> </drivers> </datasources> </subsystem>
次にJDBCドライバを実際にModuleとして登録する設定を書く。%JBOSS_HOME%/modules/com/oracle/db/main/というディレクトリを作り、同ディレクトリにJDBCドライバであるojdbc6.jarを置いて、同ディレクトリにmodule.xmlというファイルを作る。module.xmlの中身は下記のような感じ。
<?xml version="1.0" encoding="UTF-8"?> <module xmlns="urn:jboss:module:1.1" name="com.oracle.db"> <resources> <resource-root path="ojdbc6.jar"/> <!-- Insert resources here --> </resources> <dependencies> <module name="javax.api"/> <module name="javax.transaction.api"/> </dependencies> </module>
これで準備OK、あとはJava側でコードを書く。下記はサンプルのプロジェクトからそのまんまコピペのコード。サンプルはCDIが設定してあるため、アノテーション書けばEntityManagerのインスタンスが注入されるので、そっからJPAでデータアクセスするコードが書ける。
@RequestScoped public class MemberListProducer { @Inject private EntityManager em; @PostConstruct public void retrieveAllMembersOrderedByName() { CriteriaBuilder cb = em.getCriteriaBuilder(); ... } }
その他
バージョンによるのかもしれないが、hibernate.dialectのプロパティが無いとかでJPAというかHiberenateが起動しないときがある。ダイアレクトを指定してやればいいんだが、しかし困ったことにhiberenate-core-4.1.0.Final.jarにはOracle 11g用のダイアクレトのクラスが存在しない。しかし、件のエントリによると「無いなら作ればいいじゃない(意訳)」ということらしく、とりあえずは下記のようなクラスを普通に作ってしまえばよい。
package org.hibernate.dialect; import java.sql.Types; public class Oracle11gDialect extends Oracle10gDialect { public Oracle11gDialect() { registerColumnType(Types.BOOLEAN, "number(1,0)"); } }
上記はschema autocreationを使う場合らしい*1ので、要らなければOracle10gDialectをプロパティに指定しても良いかもしれないが、試してないんで分からない。
persistence.xmlはこうなる。
<properties> <property name="hibernate.dialect" value="org.hibernate.dialect.Oracle11gDialect" /> <property name="hibernate.show_sql" value="true" /> </properties>
また、org.hibernate.dialect.*がビルドに必要となる関係でpom.xmlにhibernate-coreの依存性を追加する。
<dependency> <groupId>org.hibernate</groupId> <artifactId>hibernate-core</artifactId> <version>4.1.0.Final</version> <scope>provided</scope> </dependency>
*1:というのは俺がschema autocreation使ったことないので