#author("2019-01-30T06:38:35+00:00","","")
#topicpath
----

アプリケーションを作成していると、一つのデータベースだけではなく、複数のデータベースに接続することがあります((管理用DBと参照DBなど))。
Torqueで複数のデータベースに接続する方法を調べていましたのですが、どうもうまくいきません。以下、いろいろと試行錯誤した作業メモです。

#contents
**環境 [#ka8df3c8]
複数のデータベースとして
|''DB''|''Table''|
|firstdb|person1|
|seconddb|person2|
を作成して、Torque経由で二つのテーブルからデータを取得します。

その他の環境は
|DBサーバ|Redhat Linux 8.0(2.4.20-28.8)|
|~|IP:192.168.10.3|
|DB|PostgreSQL 7.2.4|
|クライアント(Torque実行環境)|WindowsXP|
|JDK|1.4.2_03-b02|
|Torque-gen|3.1|
|Torque|3.1|
|JDBC|postgresql-jdbc-7.2.4-5.80のRPMに付属していたもの|
|~|jdbc7.2dev-1.2.jar|
|Build Tool|Apache Ant version 1.6.0 compiled on December 18 2003|


てな感じです。

**準備 [#cd193984]
*** firstdb作成 [#gff0c379]
 [root@kino root]# su - postgres
 -bash-2.05b$ createdb firstdb
 CREATE DATABASE
 -bash-2.05b$ psql firstdb
 Welcome to psql, the PostgreSQL interactive terminal.
 
 Type:  \copyright for distribution terms
        \h for help with SQL commands
        \? for help on internal slash commands
        \g or terminate with semicolon to execute query
        \q to quit
 
 firstdb=# CREATE TABLE person1 (
 firstdb(#   id INTEGER NOT NULL,
 firstdb(#   name VARCHAR(255),
 firstdb(#   PRIMARY KEY(id)
 firstdb(# );
 
 NOTICE:  CREATE TABLE / PRIMARY KEY will create implicit index 'person1_pkey' for table 'person1'
 CREATE
 firstdb=# INSERT INTO person1 (id, name) VALUES (1, 'John');
 INSERT 18937 1
 
 firstdb=# select * from person1
 firstdb-# ;
  id | name
 ----+------
   1 | John
 (1 row)
 
 firstdb=#
 
***seconddb作成 [#rfb985b1]
 -bash-2.05b$ createdb seconddb
 CREATE DATABASE
 -bash-2.05b$ psql seconddb
 Welcome to psql, the PostgreSQL interactive terminal.
 
 Type:  \copyright for distribution terms
        \h for help with SQL commands
        \? for help on internal slash commands
        \g or terminate with semicolon to execute query
        \q to quit
 
 seconddb=# CREATE TABLE person2 (
 seconddb(#   id INTEGER NOT NULL,
 seconddb(#   name VARCHAR(255),
 seconddb(#   PRIMARY KEY(id)
 seconddb(# );
 NOTICE:  CREATE TABLE / PRIMARY KEY will create implicit index 'person2_pkey' for table 'person2'
 CREATE
 seconddb=# INSERT INTO person2 (id, name) VALUES (1, 'Bob');
 INSERT 18942 1
 seconddb=# select * from person2;
  id | name
 ----+------
   1 | Bob
 (1 row)
 
 seconddb=#

**Torque-gen [#m23d5f81]
***firstdb用のソース作成 [#y3961a37]
build.propertiesを以下のように修正しました。
#ref(build.properties.firstdb)
 torque.project = firstdb
 torque.targetPackage = kino.torque.firstdb
 
 torque.database.createUrl = jdbc:postgresql://192.168.10.3:5432/firstdb
 torque.database.buildUrl = jdbc:postgresql://192.168.10.3:5432/firstdb
 torque.database.url = jdbc:postgresql://192.168.10.3:5432/firstdb
 torque.database.driver = org.postgresql.Driver
 torque.database.user = postgres
 torque.database.password =
 torque.database.host = 192.168.10.3
そして、antを実行しました。
 ant -f build-torque.xml jdbc
生成されたschema.xmlをfirstdb-schema.xmlにリネームして、
 ant -f build-torque.xml
を実行しました。
#ref(firstdb-schema.xml)
以上でfirstdbのソースコード生成は完了です。


***seconddb用のソース作成 [#h4dc196e]
build.propertiesを以下のように修正しました。
#ref(build.properties.seconddb)
 torque.project = seconddb
 torque.targetPackage = kino.torque.seconddb
 
 torque.database.createUrl = jdbc:postgresql://192.168.10.3:5432/seconddb
 torque.database.buildUrl = jdbc:postgresql://192.168.10.3:5432/seconddb
 torque.database.url = jdbc:postgresql://192.168.10.3:5432/seconddb
 torque.database.driver = org.postgresql.Driver
 torque.database.user = postgres
 torque.database.password =
 torque.database.host = 192.168.10.3
そして、antを実行しました。
 ant -f build-torque.xml jdbc
生成されたschema.xmlをseconddb-schema.xmlにリネームして、
 ant -f build-torque.xml
を実行しました。
#ref(seconddb-schema.xml)
以上でseconddbのソースコード生成は完了です。

最終的にTorque用のソースコードは以下になりました。
#ref(source.tar.gz)



**Torque [#f24f9543]
いよいよ先に生成したソースコードを用いてデータベースにアクセスします。

***Torque.propertiesの修正 [#sbd2ec2f]
Torque.propertiesは以下のように修正しました。基本的にほとんどの行をコメントアウトして、以下の内容(firstdbとseconddbの情報)を追加しました。
 torque.dsfactory.firstdb.factory=org.apache.torque.dsfactory.SharedPoolDataSourceFactory
 torque.dsfactory.firstdb.connection.url = jdbc:postgresql://192.168.10.3:5432/firstdb
 torque.dsfactory.firstdb.connection.user = postgres
 torque.dsfactory.firstdb.connection.password = 
 
 torque.dsfactory.seconddb.factory=org.apache.torque.dsfactory.SharedPoolDataSourceFactory
 torque.dsfactory.seconddb.connection.driver = org.postgresql.Driver
 torque.dsfactory.seconddb.connection.url = jdbc:postgresql://192.168.10.3:5432/seconddb
 torque.dsfactory.seconddb.connection.user = postgres
 torque.dsfactory.seconddb.connection.password = 

#ref(Torque.properties)

***build.xmlの作成 [#bdad0f4a]
Javaのクラスをコンパイルしてテストプログラムを実行するためのbuild.xmlを作成しました。また、テストプログラムとしてSampleMain.javaを作成しました。

#ref(build.xml)~
#ref(SampleMain.java)

***いよいよ実行 [#ud27a921]
いよいよ実行です。
 ant java
としましたが、エラーになってしまいました。
#ref(error.log)
エラー内容ですが、みてみると
 java.lang.NullPointerException: There was no DataSourceFactory configured for the connection default
となっていて、デフォルト値の設定がないよっておこってるみたいです。

***試しに [#s333ab9f]
試しに
 torque.database.default=firstdb
を追記したところ、firstdbにはつながるけどもseconddbにはつながらない
java.sql.SQLException: ERROR:  Relation "person2" does not exist となってしまう

逆に
 torque.database.default=seconddb
を追記したところ、seconddbにはつながるけどもfirstdbにはつながらない
java.sql.SQLException: ERROR:  Relation "person1" does not exist となってしまう

という状況でした。デフォルト値の指定をすると、データの取得はできているみたいです。

**解決! [#y06b2eeb]
解決しました。~
xxxx-schema.xmlのdatabase要素にはname属性を記述可能なのですが、どうもそれがデータソースを識別しているようです。((ここでいっているデータソースってのは、巡り巡って、Torque.propertiesのtorque.dsfactory.firstdb.factory=org.apache.torque.dsfactory.SharedPoolDataSourceFactoryなどの「firstdb」のこと))
 ant -f build-torque.xml jdbc
で生成されたschema.xmlには、なぜかname属性が省略されていて、そうすると
 ant -f build-torque.xml
で生成されるソースコード(たとえばBasePerson1Peer.java)に
 public static final String DATABASE_NAME = "default";
と"default"と書かれてしまうみたいです。ソースコードにdefaultと書かれてしまうために、Torque.properties内でtorque.database.defaultで指定したデータベースにしかつながらないのかなと判断しました。((torque.database.default=の右辺をみてtorque.dsfactory.右辺の値.factoryを参照するってながれ?))

とするとxxxx-schema.xmlのdatabase要素のname属性で指定した値で、Torque.propertiesを記述しなくてはいけないということでしょうか?何となく釈然としないのは私だけ?

***追加手順 [#f7e03ce5]
何はともあれ、解決策が見つかりましたので、追加の手順です。先ほどのTorque.propertiesには
 torque.dsfactory.firstdb.factory
 torque.dsfactory.seconddb.factory
などと書いたので、xxxx-schema.xmlの<database>をそれぞれ
 <database name="firstdb">
 <database name="seconddb">
に変更し、antでソースコードを再作成しました。((確かにpublic static final String DATABASE_NAME = "firstdb";などとなっている))

***再度実行 [#ac960118]
antでもう一度サンプルプログラムを実行したところ、ようやくうまくいきました。両方のテーブルからデータ取得ができました!!
#ref(実行結果.txt)

----
この記事は
#vote(おもしろかった[24],そうでもない[0])
#vote(おもしろかった[25],そうでもない[0])


#topicpath

SIZE(10){現在のアクセス:&counter;}

トップ   編集 差分 バックアップ 添付 複製 名前変更 リロード   新規 一覧 単語検索 最終更新   ヘルプ   最終更新のRSS