1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

CAP (Java)でPostgreSQLを使う方法

Last updated at Posted at 2025-01-21

はじめに

この記事では、CAP (Java) のアプリケーションでBTPのPostgreSQLをデータベースとして使用する方法について紹介します。

過去の記事でコミュニティ開発のモジュールであるcds-pgおよびcds-dbmを使用した方法を紹介しましたが、cds 7.xから@cap-js/postgresが登場してPostgreSQLの使用が公式にサポートされるようになりました。これにともない、cds-pgcds-dbmはdeprecatedとなっています。

関連ブログ

実施すること

  • ローカル実行にはインメモリデータベース(H2)を使用する
  • Cloud FoundryではPostreSQLを使用する

※ハイブリッド実行でPostgreSQLに接続できないか試してみましたが、うまくいきませんでした(「ハイブリッド実行で試したこと」を参照)。

バージョン
@sap/cds: 8.6.1
@sap/cds-dk: 8.4.2

開発環境
SAP Business Application Studio

ステップ

  1. プロジェクトの作成
  2. サンプルサービスの設定
  3. PostgreSQLを追加
  4. デプロイのための設定
  5. ビルド、デプロイ
  6. 動作確認

1. プロジェクトの作成

CAP (Java) のプロジェクトを作成します。

cds init cap-java-postgresql --add java

2. サンプルサービスの設定

サンプルサービスを追加します。

cds add tiny-sample

以下のコマンドでサービスを実行します。

mvn spring-boot:run

image.png

3. PostgreSQLを追加

以下のコマンドでPostgreSQLのための設定を追加します。

cds add postgres

この結果、以下の設定が追加されます。

srv/pom.xml
		<dependency>
			<groupId>com.sap.cds</groupId>
			<artifactId>cds-feature-postgresql</artifactId>
			<scope>runtime</scope>
		</dependency>
package.json
  "dependencies": {
    "@cap-js/postgres": "^1"
  }
srv/src/main/resources/application.yaml
---
spring:
  datasource:
    password: postgres
    embedded-database-connection: none
    driver-class-name: org.postgresql.Driver
    url: jdbc:postgresql://localhost:5432/postgres
    username: postgres
  config:
    activate:
      on-profile: default

application.yamlの設定を元に戻す

application.yamlがローカル実行時もローカルのPostgreSQLに接続する設定に変更されたので、このままmvn spring-boot:runを実行するとDBに接続できずにエラーになります。ローカル実行時にはこれまで通りH2データベースに接続するため、デフォルトのプロファイルを元に戻します。

application.yamlの全体は以下のようになります。

---
spring:
  config.activate.on-profile: default
  sql.init.schema-locations: classpath:schema-h2.sql
cds:
  data-source.auto-config.enabled: false

4. デプロイのための設定

mta.yamlを追加します。

cds add mta

mta.yamlファイルを開き、サービスのpropertiesに以下の設定を追加します。<POSTGRESQL_SERVICE_NAME>には、PostgreSQLのサービス名(mta.yamlのresourcesセクション参照)を設定します。

CFENV_SERVICE_<POSTGRESQL_SERVICE_NAME>_ENABLED: false

設定の意味
デフォルトではjava_buildpackがPostgreSQLデータソースを初期化します。CAPで動かすためにはPostreSQLのデータソースはCAP Javaランタイムが作成する必要があるため、ビルドパックによるデータソースの初期化を無効化しています。(参考:Provisioning a DB Instance

以下は設定例です。

mta.yaml
modules:
  - name: cap-java-postgresql2-srv
    type: java
    path: srv
    parameters:
      buildpack: sap_java_buildpack_jakarta
      readiness-health-check-type: http
      readiness-health-check-http-endpoint: /actuator/health/readiness
    properties:
      SPRING_PROFILES_ACTIVE: cloud,sandbox
      JBP_CONFIG_COMPONENTS: "jres: ['com.sap.xs.java.buildpack.jre.SAPMachineJRE']"
      JBP_CONFIG_SAP_MACHINE_JRE: '{ version: 21.+ }'
      CFENV_SERVICE_CAP-JAVA-POSTGRESQL-POSTGRES_ENABLED: false #追加

ビルドの設定

postgresqlのデプロイヤーはgen/pgフォルダ配下にあるビルド結果を使用しますが、生成されたmta.yamlにはビルドのためのコマンドがありません。そこで、mta.yamlの先頭に以下の設定を追加します。cds build --productionコマンドによりgen/pgフォルダが生成されます。

build-parameters:
  before-all:
    - builder: custom
      commands:
        - npx cds build --production  

先頭部分は全体で以下のようになります。

_schema-version: 3.3.0
ID: cap-java-postgresql2
version: 1.0.0-SNAPSHOT
description: "A simple CAP project."
parameters:
  enable-parallel-deployments: true
build-parameters:
  before-all:
    - builder: custom
      commands:
        - npx cds build --production  

application.yamlの設定

デプロイしたサービスからPostgreSQLに接続できるよう、application.yamlに以下の設定を追加します。(参考:Run and Deploy SAP CAP (Java) with PostgreSQL using Official Database Adapter @cap-js/postgres

---
spring:
  config.activate.on-profile: cloud
  datasource:
      driver-class-name: org.postgresql.Driver
      url: jdbc:postgresql://${vcap.services.<POSTGRESQL_SERVICE_NAME>.credentials.hostname}:${vcap.services.<POSTGRESQL_SERVICE_NAME>.credentials.port}/${vcap.services.<POSTGRESQL_SERVICE_NAME>.credentials.dbname}
      username: ${vcap.services.<POSTGRESQL_SERVICE_NAME>.credentials.username}
      password: ${vcap.services.<POSTGRESQL_SERVICE_NAME>.credentials.password}
---
spring:
  config.activate.on-profile: cloud
  datasource:
      driver-class-name: org.postgresql.Driver
      url: jdbc:postgresql://${vcap.services.cap-java-postgresql-postgres.credentials.hostname}:${vcap.services.cap-java-postgresql-postgres.credentials.port}/${vcap.services.cap-java-postgresql-postgres.credentials.dbname}
      username: ${vcap.services.cap-java-postgresql-postgres.credentials.username}
      password: ${vcap.services.cap-java-postgresql-postgres.credentials.password}  

ドキュメントには記載がなかったのですが、この設定がないとBooksエンティティを照会しようとしたときに以下のエラーが返されました。

{
    "error": {
        "code": "50003009",
        "message": "Failed to start a new transaction"
    }
}

postgresql-dbサービスプランを変更(トライアルアカウントの場合)

resourcesセクションに追加されたpostgresql-dbサービスには、デフォルトではdevelopmentプランが設定されています。トライアルアカウントを使用している場合はサービスプランをtrialに変更します。

resources:
  - name: cap-java-postgresql2-postgres
    type: org.cloudfoundry.managed-service
    parameters:
      service: postgresql-db
      service-plan: development

トライアルアカウントの場合、作成できるサービスインスタンスは1つまでです。

5. ビルド、デプロイ

以下のコマンドでビルド、デプロイします。

mbt build -t gen --mtar mta.tar
cf deploy gen/mta.tar

6. 動作確認

デプロイされたサービスにアクセスし、データが取得できることを確認します。
image.png

ハイブリッド実行で試したこと

BASからBTPのPostgreSQLに接続しようと以下のことを行いましたが、接続できませんでした。

  • PostgreSQLのインスタンスをバインド
cds bind db --to cap-java-postgresql-postgres
  • application.yamlにハイブリッド用の設定を追加
---
spring:
  config.activate.on-profile: hybrid
  datasource:
      driver-class-name: org.postgresql.Driver
      url: jdbc:postgresql://${vcap.services.cap-java-postgresql-postgres.credentials.hostname}:${vcap.services.cap-java-postgresql-postgres.credentials.port}/${vcap.services.cap-java-postgresql-postgres.credentials.dbname}
      username: ${vcap.services.cap-java-postgresql-postgres.credentials.username}
      password: ${vcap.services.cap-java-postgresql-postgres.credentials.password}    
  • ハイブリッドモードで実行
cds bind --exec -- mvn spring-boot:run \
  -Dspring-boot.run.profiles=default,hybrid

結果、"vcap.services.cap-java-postgresql.credentials.hostnameが見つからない"というエラーになりました。

java.lang.IllegalArgumentException: Could not resolve placeholder 'vcap.services.cap-java-postgresql.credentials.hostname' in value "jdbc:postgresql://${vcap.services.cap-java-postgresql.credentials.hostname}...

以下のコマンドで、環境変数VCAP_SERVICESがBTP環境と同じように設定されていることを確認しました。

cds bind --exec -- node -e 'console.log(process.env.VCAP_SERVICES)'
1
1
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
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?