LoginSignup
1
3

More than 3 years have passed since last update.

がんばってSpring BootとJDBCでIBM CloudのDb2に接続する

Last updated at Posted at 2020-11-01

どうしてこの記事を書くことになったのか:

知恵袋みたいなアプリケーションに投稿されたデータを、チャットボット(もちろんIBM Cloud上の)から検索かけられたら強そう! 将来的に自然言語解析もできそう! と思ったので一時のテンションで始めたらエラーだらけだった。

前提

・IBM Cloudにアカウントがある
・Db2のリソースが作成済み(ライトアカウント)

わかるところから

DB2 via JDBC on Spring - IBM Developer

とりあえず検索して出てきた上記のページを参考に、application.propertiesを書く。
(IBM Cloud>リソース・リスト>作成したDb2>サービス資格情報 からURLなどの情報が取得できる)

application.properties
spring.datasource.url=jdbc:db2://**************:50000/BLUDB
spring.datasource.username=********
spring.datasource.password=********

エラー1個目

***************************
APPLICATION FAILED TO START
***************************
Description:
Failed to bind properties under '' to com.zaxxer.hikari.HikariDataSource:
    Property: driverclassname
    Value: com.ibm.db2.jcc.DB2Driver
    Origin: "driverClassName" from property source "source"
    Reason: Failed to load driver class com.ibm.db2.jcc.DB2Driver in either of HikariConfig class loader or Thread context classloader
Action:
Update your application's configuration

Stack Overflowのこの質問を参考にしてbuild.gradleを編集した。

対処

build.gradle
dependencies {
    runtime('com.ibm.db2:jcc:11.5.0.0')
}

エラー2個目

2020-00-00 15:21:58.916 ERROR 5080 --- [  restartedMain] com.zaxxer.hikari.pool.HikariPool        : HikariPool-1 - Exception during pool initialization.
com.ibm.db2.jcc.am.SqlSyntaxErrorException: DB2 SQL Error: SQLCODE=-104, SQLSTATE=42601, SQLERRMC=END-OF-STATEMENT;select 1;<table_expr>, DRIVER=4.26.14

上記は起動時に発生するエラー。内容的にはSQLのシンタックスエラーだが、起動時にSQLを使った覚えがなく、ずっとimport.sqlが悪いのか?起動時にテーブルを生成する設定が悪いのか?などと考えていた。
しかし結局、ここで作動していたのは接続テスト用に(おそらくデフォルトで)設定されていたSQLだった……。
いろいろ調べていくうちに気づいたが、エラー文にあったSELECT 1で検索を書けていたらもっと早く気づけたかもしれない。

application.properties
spring.datasource.hikari.connection-test-query = SELECT 1

このSQL文がおかしいということで、Db2向けの適当なテスト用SQLがあるんじゃないか?と調べてみたけどヒットせず。
ならこのオプション外せばいいじゃんと思ったが、HikariCPでは代わりにConnection.isValid()を実行するようになり、結局エラーが出た。
なら存在する任意のテーブルに対して何か操作すればいいんじゃないということで、適当にtestテーブルにカラムを一つ作成した。

対処

application.properties
spring.datasource.hikari.connection-test-query = SELECT col1 from test

さらに数か所修正

  • spring.jpa.database-platformorg.hibernate.dialect.h2Dialectからorg.hibernate.dialect.DB2Dialectにしたり…(最初H2で作っていたので)
  • Javaのソースコード中のSQL文からセミコロンを外したり…(おそらく上記との兼ね合い)
  • タイムアウトの時間を長くしたり…(ライトプランのせいか頻繁にタイムアウトする)
  • pom.xmlを書き換えたり…(下記)
pom.xml
<dependency>
    <groupId>com.ibm.db2</groupId>
    <artifactId>jcc</artifactId>
    <version>11.5.0.0</version>
</dependency>

アクセスできた!

本当にこれでいいのか? という疑問はありつつも一応アクセスできたのでOKとする。
すごい…ちゃんとブラウザ上にデータが表示されている…。
と思ったのもつかの間、

エラー3個目

2020-00-00 01:22:57.438  WARN 26912 --- [nio-8080-exec-1] o.h.engine.jdbc.spi.SqlExceptionHelper   : [jcc][t4][10217][10310][4.26.14] 接続の確立後は、接続の読み取り専用モードを実行できません。
読み取り専用の接続を実行するには、読み取り専用データ・ソースまたは接続プロパティーを設定してください。 ERRORCODE=4474, SQLSTATE=01000

DriverManager.getConnection()でアクセスしている分には出ないので、どうもJPARepositoryを介してアクセスしようとするとこのエラーになるらしい。
(混在しているのは自分で書いたコードと人の書いたコードが混ざっているせい……)
JPARepositoryを使わなければひとまず解決しそうだけど、普通に設定変えて使えるような気もする。
第二弾記事に期待。

まとめ

  • application.propertiesbuild.gradleあたりが怪しい。
  • エラー文をちゃんと読む

余談

Db2のダッシュボードにアクセスしようとすると延々とエラーを吐き続けるという不具合に当たったが、ダッシュボードのアドレスが分かれば、そちらにアクセスして、DBの認証で使っているusernameとpasswordを入力してアクセスすることができる。
リダイレクトするときに、IBMCloudのログイン情報からダッシュボードへの認証がうまくできなかったみたい。

1
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
3