1. 概要

永続層を作成するときは、SQLデータベーススキーマをコードで作成したオブジェクトモデルと一致させる必要があります。 これは、手動で行うには多くの作業になる可能性があります。

このチュートリアルでは、コードのエンティティモデルに基づいてデータベーススキーマを生成およびエクスポートする方法を説明します。

最初に、スキーマ生成のJPA構成プロパティについて説明します。 次に、Spring DataJPAでこれらのプロパティを使用する方法について説明します。

最後に、HibernateのネイティブAPIを使用したDDL生成の代替案を検討します。

2. JPAスキーマの生成

JPA 2.1では、データベーススキーマ生成の標準が導入されました。 したがって、このリリース以降、事前定義された構成プロパティのセットを使用して、データベーススキーマを生成およびエクスポートする方法を制御できます。

2.1. スクリプトアクション

まず、生成するDDLコマンドを制御するために、JPAはスクリプトaction構成オプションを導入します。

javax.persistence.schema-generation.scripts.action

4つの異なるオプションから選択できます。

  • none –DDLコマンドを生成しません
  • create –データベース作成コマンドのみを生成します
  • drop –データベースドロップコマンドのみを生成します
  • drop-and-create –データベースのドロップコマンドとそれに続く作成コマンドを生成します

2.2. スクリプトターゲット

次に、指定されたスクリプト action ごとに、対応するtarget構成を定義する必要があります。

javax.persistence.schema-generation.scripts.create-target
javax.persistence.schema-generation.scripts.drop-target

基本的に、スクリプト target は、スキーマの作成またはドロップコマンドを含むファイルの場所を定義します。 したがって、たとえば、スクリプトアクションとしてドロップアンドクリエイトを選択した場合、両方のターゲットを指定する必要があります。

2.3. スキーマソース

最後に、エンティティモデルからスキーマDDLコマンドを生成するには、メタデータオプションを選択したスキーマソース構成を含める必要があります。

javax.persistence.schema-generation.create-source=metadata
javax.persistence.schema-generation.drop-source=metadata

次のセクションでは、Spring Data JPAを使用して、標準のJPAプロパティを使用してデータベーススキーマを自動的に生成する方法を示します。

3. SpringDataJPAを使用したスキーマ生成

3.1. モデル

アカウントと呼ばれるエンティティを使用してユーザーアカウントシステムを実装していると想像してみてください。

@Entity
@Table(name = "accounts")
public class Account {
    
    @Id
    @GeneratedValue
    private Long id;

    @Column(nullable = false, length = 100)
    private String name;

    @Column(name = "email_address")
    private String emailAddress;

    @OneToMany(mappedBy = "account", cascade = CascadeType.ALL)
    private List<AccountSettings> accountSettings = new ArrayList<>();

    // getters and setters
}

各アカウントは複数のアカウント設定を持つことができるため、ここでは1対多マッピングを行います。

@Entity
@Table(name = "account_settings")
public class AccountSetting {

    @Id
    @GeneratedValue
    private Long id;

    @Column(name = "name", nullable = false)
    private String settingName;

    @Column(name = "value", nullable = false)
    private String settingValue;

    @ManyToOne
    @JoinColumn(name ="account_id", nullable = false)
    private Account account;

    // getters and setters
}

3.2. SpringDataJPA構成

データベーススキーマを生成するには、使用中の永続性プロバイダーにスキーマ生成プロパティを渡す必要があります。 これを行うには、構成ファイルの spring.jpa.propertiesプレフィックスの下にネイティブJPAプロパティを設定します。

spring.jpa.properties.javax.persistence.schema-generation.scripts.action=create
spring.jpa.properties.javax.persistence.schema-generation.scripts.create-target=create.sql
spring.jpa.properties.javax.persistence.schema-generation.scripts.create-source=metadata

したがって、 Spring Data JPAは、 EntityManagerFactory Beanを作成するときに、これらのプロパティを永続性プロバイダーに渡します。

3.3. create.sqlファイル

その結果、アプリケーションの起動時に、上記の構成により、エンティティマッピングメタデータに基づいてデータベース作成コマンドが生成されます。 さらに、DDLコマンドは create.sql ファイルにエクスポートされます。このファイルは、メインのプロジェクトフォルダーに作成されます。

create table account_settings (
    id bigint not null,
    name varchar(255) not null,
    value varchar(255) not null,
    account_id bigint not null,
    primary key (id)
)

create table accounts (
    id bigint not null,
    email_address varchar(255),
    name varchar(100) not null,
    primary key (id)
)

alter table account_settings
   add constraint FK54uo82jnot7ye32pyc8dcj2eh
   foreign key (account_id)
   references accounts (id)

4. HibernateAPIを使用したスキーマ生成

Hibernateを使用している場合、ネイティブAPIであるSchemaExportを直接使用して、スキーマDDLコマンドを生成できます。 同様に、Hibernate APIは、アプリケーションエンティティモデルを使用してデータベーススキーマを生成およびエクスポートします。

HibernateのSchemaExportを使用すると、 drop createOnly、、およびcreateメソッドを明示的に使用できます。

MetadataSources metadataSources = new MetadataSources(serviceRegistry);
metadataSources.addAnnotatedClass(Account.class);
metadataSources.addAnnotatedClass(AccountSettings.class);
Metadata metadata = metadataSources.buildMetadata();

SchemaExport schemaExport = new SchemaExport();
schemaExport.setFormat(true);
schemaExport.setOutputFile("create.sql");
schemaExport.createOnly(EnumSet.of(TargetType.SCRIPT), metadata);

このコードを実行すると、データベース作成コマンドがメインプロジェクトフォルダーのcreate.sqlファイルにエクスポートされます。

SchemaExport は、 Hibernate BootstrappingAPIの一部です。

5. スキーマ生成オプション

スキーマ生成は開発中の時間を節約できますが、基本的なシナリオでのみ使用する必要があります。

たとえば、これを使用して、開発データベースやテストデータベースをすばやく起動できます。

対照的に、データベースの移行などのより複雑なシナリオでは、LiquibaseやFlywayなどのより洗練されたツールを使用する必要があります。

6. 結論

このチュートリアルでは、JPA schema-generationプロパティを使用してデータベーススキーマを生成およびエクスポートする方法を説明しました。 続いて、HibernateのネイティブAPI SchemaExportを使用して同じ結果を達成する方法を確認しました。

いつものように、サンプルコードはGitHubにあります。