データアクセス
Spring Boot には、データソースを操作するためのスタータが多数含まれています。このセクションでは、その方法に関する質問に回答します。
カスタム DataSource を構成する
独自の DataSource
(標準 Javadoc) を設定するには、その型の @Bean
(Javadoc) を設定で定義します。Spring Boot は、データベースの初期化など、必要な場所で DataSource
(標準 Javadoc) を再利用します。一部の設定を外部化する必要がある場合は、DataSource
(標準 Javadoc) を環境にバインドできます ( サードパーティの構成を参照)。
次の例は、Bean でデータソースを定義する方法を示しています。
Java
Kotlin
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration(proxyBeanMethods = false)
public class MyDataSourceConfiguration {
@Bean
@ConfigurationProperties(prefix = "app.datasource")
public SomeDataSource dataSource() {
return new SomeDataSource();
}
}
import org.springframework.boot.context.properties.ConfigurationProperties
import org.springframework.context.annotation.Bean
import org.springframework.context.annotation.Configuration
@Configuration(proxyBeanMethods = false)
class MyDataSourceConfiguration {
@Bean
@ConfigurationProperties(prefix = "app.datasource")
fun dataSource(): SomeDataSource {
return SomeDataSource()
}
}
次の例は、プロパティを設定してデータソースを定義する方法を示しています。
プロパティ
YAML
app.datasource.url=jdbc:h2:mem:mydb
app.datasource.username=sa
app.datasource.pool-size=30
app:
datasource:
url: "jdbc:h2:mem:mydb"
username: "sa"
pool-size: 30
SomeDataSource
に URL、ユーザー名、プールサイズの通常の JavaBean プロパティがあると仮定すると、これらの設定は、DataSource
(標準 Javadoc) が他のコンポーネントで使用できるようになる前に自動的にバインドされます。
Spring Boot は、標準データソースの 1 つ (クラスパス上にある場合) を作成するために使用できる、DataSourceBuilder
(Javadoc) と呼ばれるユーティリティビルダークラスも提供します。ビルダーは、クラスパスで使用可能なものに基づいて、使用するデータソースを検出できます。また、JDBC URL に基づいてドライバーを自動検出します。
次の例は、DataSourceBuilder
(Javadoc) を使用してデータソースを作成する方法を示しています。
Java
Kotlin
import javax.sql.DataSource;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.jdbc.DataSourceBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration(proxyBeanMethods = false)
public class MyDataSourceConfiguration {
@Bean
@ConfigurationProperties("app.datasource")
public DataSource dataSource() {
return DataSourceBuilder.create().build();
}
}
import javax.sql.DataSource
import org.springframework.boot.context.properties.ConfigurationProperties
import org.springframework.boot.jdbc.DataSourceBuilder
import org.springframework.context.annotation.Bean
import org.springframework.context.annotation.Configuration
@Configuration(proxyBeanMethods = false)
class MyDataSourceConfiguration {
@Bean
@ConfigurationProperties("app.datasource")
fun dataSource(): DataSource {
return DataSourceBuilder.create().build()
}
}
その DataSource
(標準 Javadoc) を使用してアプリを実行するには、接続情報だけが必要です。プール固有の設定も提供できます。詳細については、実行時に使用される実装を確認してください。
次の例は、プロパティを設定して JDBC データソースを定義する方法を示しています。
プロパティ
YAML
app.datasource.url=jdbc:mysql://localhost/test
app.datasource.username=dbuser
app.datasource.password=dbpass
app.datasource.pool-size=30
app:
datasource:
url: "jdbc:mysql://localhost/test"
username: "dbuser"
password: "dbpass"
pool-size: 30
ただし、メソッドの戻り値の型が DataSource
(標準 Javadoc) であるため、問題があります。これにより、接続プールの実際の型が非表示になるため、カスタム DataSource
(標準 Javadoc) の構成プロパティメタデータは生成されず、IDE で自動補完は使用できません。この問題を解決するには、ビルダーの type(Class)
メソッドを使用して、構築する DataSource
(標準 Javadoc) の型を指定し、メソッドの戻り値の型を更新します。例: 以下は、DataSourceBuilder
(Javadoc) を使用して HikariDataSource
(英語) を作成する方法を示しています。
Java
Kotlin
import com.zaxxer.hikari.HikariDataSource;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.jdbc.DataSourceBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration(proxyBeanMethods = false)
public class MyDataSourceConfiguration {
@Bean
@ConfigurationProperties("app.datasource")
public HikariDataSource dataSource() {
return DataSourceBuilder.create().type(HikariDataSource.class).build();
}
}
import com.zaxxer.hikari.HikariDataSource
import org.springframework.boot.context.properties.ConfigurationProperties
import org.springframework.boot.jdbc.DataSourceBuilder
import org.springframework.context.annotation.Bean
import org.springframework.context.annotation.Configuration
@Configuration(proxyBeanMethods = false)
class MyDataSourceConfiguration {
@Bean
@ConfigurationProperties("app.datasource")
fun dataSource(): HikariDataSource {
return DataSourceBuilder.create().type(HikariDataSource::class.java).build()
}
}
残念ながら、Hikari には url
プロパティがないため、この基本設定は機能しません。代わりに、jdbc-url
プロパティがあるため、構成を次のように書き換える必要があります。
プロパティ
YAML
app.datasource.jdbc-url=jdbc:mysql://localhost/test
app.datasource.username=dbuser
app.datasource.password=dbpass
app.datasource.pool-size=30
app:
datasource:
jdbc-url: "jdbc:mysql://localhost/test"
username: "dbuser"
password: "dbpass"
pool-size: 30
この問題に対処するには、url
から jdbc-url
への変換を処理する DataSourceProperties
(Javadoc) を使用します。initializeDataSourceBuilder()
メソッドを使用して、任意の DataSourceProperties
(Javadoc) オブジェクトの状態から DataSourceBuilder
(Javadoc) を初期化できます。Spring Boot が自動的に作成する DataSourceProperties
(Javadoc) を挿入することもできますが、そうすると構成が spring.datasource.*
と app.datasource.*
に分割されます。これを回避するには、次の例に示すように、カスタム構成プロパティプレフィックスを使用してカスタム DataSourceProperties
(Javadoc) を定義します。
Java
Kotlin
import com.zaxxer.hikari.HikariDataSource;
import org.springframework.boot.autoconfigure.jdbc.DataSourceProperties;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
@Configuration(proxyBeanMethods = false)
public class MyDataSourceConfiguration {
@Bean
@Primary
@ConfigurationProperties("app.datasource")
public DataSourceProperties dataSourceProperties() {
return new DataSourceProperties();
}
@Bean
@ConfigurationProperties("app.datasource.configuration")
public HikariDataSource dataSource(DataSourceProperties properties) {
return properties.initializeDataSourceBuilder().type(HikariDataSource.class).build();
}
}
import com.zaxxer.hikari.HikariDataSource
import org.springframework.boot.autoconfigure.jdbc.DataSourceProperties
import org.springframework.boot.context.properties.ConfigurationProperties
import org.springframework.context.annotation.Bean
import org.springframework.context.annotation.Configuration
import org.springframework.context.annotation.Primary
@Configuration(proxyBeanMethods = false)
class MyDataSourceConfiguration {
@Bean
@Primary
@ConfigurationProperties("app.datasource")
fun dataSourceProperties(): DataSourceProperties {
return DataSourceProperties()
}
@Bean
@ConfigurationProperties("app.datasource.configuration")
fun dataSource(properties: DataSourceProperties): HikariDataSource {
return properties.initializeDataSourceBuilder().type(HikariDataSource::class.java).build()
}
}
この設定は、プールの型がコードで指定され、その設定が app.datasource.configuration.*
プロパティとして公開されることを除いて、Spring Boot がデフォルトで行うことと同じです。DataSourceProperties
(Javadoc) は url
から jdbc-url
への変換を処理するため、次のように構成できます。
プロパティ
YAML
app.datasource.url=jdbc:mysql://localhost/test
app.datasource.username=dbuser
app.datasource.password=dbpass
app.datasource.configuration.maximum-pool-size=30
app:
datasource:
url: "jdbc:mysql://localhost/test"
username: "dbuser"
password: "dbpass"
configuration:
maximum-pool-size: 30
カスタム構成ではコード内で Hikari を使用するように指定されているため、app.datasource.type
は効果がないことに注意してください。
サポートされている接続プールで説明したように、DataSourceBuilder
(Javadoc) はいくつかの異なる接続プールをサポートしています。Hikari 以外のプールを使用するには、そのプールをクラスパスに追加し、type(Class)
メソッドを使用して使用するプールクラスを指定し、一致するように @Bean
(Javadoc) メソッドの戻り値の型を更新します。これにより、選択した特定の接続プールの構成プロパティメタデータも提供されます。
Spring Boot は、Hikari 固有の設定を spring.datasource.hikari に公開します。この例では複数のデータソース実装をサポートしていないため、この例ではより一般的な configuration サブ名前空間を使用します。 |
詳細については、DataSource を構成するおよび DataSourceAutoConfiguration
[GitHub] (英語) クラスを参照してください。
2 つの DataSources を構成する
追加の DataSource
(標準 Javadoc) を定義するには、前のセクションと同様のアプローチを使用できます。重要な違いは、DataSource
(標準 Javadoc) @Bean
(Javadoc) を defaultCandidate=false
で宣言する必要があることです。これにより、自動構成された DataSource
(標準 Javadoc) がバックオフするのを防ぎます。
Spring Framework リファレンスドキュメントではこの機能についてさらに詳しく説明しています。 |
追加の DataSource
(標準 Javadoc) を必要な場所に挿入できるようにするには、次の例に示すように、@Qualifier
(Javadoc) もアノテーション付けします。
Java
Kotlin
import com.zaxxer.hikari.HikariDataSource;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.jdbc.DataSourceBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration(proxyBeanMethods = false)
public class MyAdditionalDataSourceConfiguration {
@Qualifier("second")
@Bean(defaultCandidate = false)
@ConfigurationProperties("app.datasource")
public HikariDataSource secondDataSource() {
return DataSourceBuilder.create().type(HikariDataSource.class).build();
}
}
import com.zaxxer.hikari.HikariDataSource
import org.springframework.beans.factory.annotation.Qualifier
import org.springframework.boot.context.properties.ConfigurationProperties
import org.springframework.boot.jdbc.DataSourceBuilder
import org.springframework.context.annotation.Bean
import org.springframework.context.annotation.Configuration
@Configuration(proxyBeanMethods = false)
class MyAdditionalDataSourceConfiguration {
@Qualifier("second")
@Bean(defaultCandidate = false)
@ConfigurationProperties("app.datasource")
fun secondDataSource(): HikariDataSource {
return DataSourceBuilder.create().type(HikariDataSource::class.java).build()
}
}
追加の DataSource
(標準 Javadoc) を消費するには、インジェクションポイントに同じ @Qualifier
(Javadoc) をアノテーション付けします。
自動構成されたデータソースと追加のデータソースは、次のように構成できます。
プロパティ
YAML
spring.datasource.url=jdbc:mysql://localhost/first
spring.datasource.username=dbuser
spring.datasource.password=dbpass
spring.datasource.configuration.maximum-pool-size=30
app.datasource.url=jdbc:mysql://localhost/second
app.datasource.username=dbuser
app.datasource.password=dbpass
app.datasource.max-total=30
spring:
datasource:
url: "jdbc:mysql://localhost/first"
username: "dbuser"
password: "dbpass"
configuration:
maximum-pool-size: 30
app:
datasource:
url: "jdbc:mysql://localhost/second"
username: "dbuser"
password: "dbpass"
max-total: 30
自動構成された DataSource
(標準 Javadoc) のより高度で実装固有の構成は、spring.datasource.configuration.*
プロパティを通じて利用できます。次の例に示すように、同じ概念を追加の DataSource
(標準 Javadoc) にも適用できます。
Java
Kotlin
import com.zaxxer.hikari.HikariDataSource;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.autoconfigure.jdbc.DataSourceProperties;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration(proxyBeanMethods = false)
public class MyCompleteAdditionalDataSourceConfiguration {
@Qualifier("second")
@Bean(defaultCandidate = false)
@ConfigurationProperties("app.datasource")
public DataSourceProperties secondDataSourceProperties() {
return new DataSourceProperties();
}
@Qualifier("second")
@Bean(defaultCandidate = false)
@ConfigurationProperties("app.datasource.configuration")
public HikariDataSource secondDataSource(
@Qualifier("secondDataSourceProperties") DataSourceProperties secondDataSourceProperties) {
return secondDataSourceProperties.initializeDataSourceBuilder().type(HikariDataSource.class).build();
}
}
import com.zaxxer.hikari.HikariDataSource
import org.springframework.beans.factory.annotation.Qualifier
import org.springframework.boot.autoconfigure.jdbc.DataSourceProperties
import org.springframework.boot.context.properties.ConfigurationProperties
import org.springframework.context.annotation.Bean
import org.springframework.context.annotation.Configuration
@Configuration(proxyBeanMethods = false)
class MyCompleteAdditionalDataSourceConfiguration {
@Qualifier("second")
@Bean(defaultCandidate = false)
@ConfigurationProperties("app.datasource")
fun secondDataSourceProperties(): DataSourceProperties {
return DataSourceProperties()
}
@Qualifier("second")
@Bean(defaultCandidate = false)
@ConfigurationProperties("app.datasource.configuration")
fun secondDataSource(secondDataSourceProperties: DataSourceProperties): HikariDataSource {
return secondDataSourceProperties.initializeDataSourceBuilder().type(HikariDataSource::class.java).build()
}
}
上記の例では、Spring Boot が自動構成で使用するのと同じロジックを使用して追加のデータソースを構成します。app.datasource.configuration.*
プロパティは、選択した実装に基づいて高度な設定を提供することに注意してください。
単一のカスタム DataSource
を構成すると同様に、DataSource
(標準 Javadoc) Bean の 1 つまたは両方の型は、DataSourceBuilder
(Javadoc) の type(Class)
メソッドを使用してカスタマイズできます。サポートされている型の詳細については、サポートされている接続プールを参照してください。
Spring Data リポジトリを使用する
Spring Data は、さまざまなフレーバーの Repository
(Javadoc) インターフェースの実装を作成できます。Repository
(Javadoc) 実装が自動構成パッケージの 1 つ (通常は、@SpringBootApplication
(Javadoc) または @EnableAutoConfiguration
(Javadoc) でアノテーションが付けられたメインアプリケーションクラスのパッケージ (またはサブパッケージ)) に含まれている限り、Spring Boot がそのすべてを処理します。
多くのアプリケーションでは、クラスパスに適切な Spring Data 依存関係を配置するだけで済みます。サポートされているテクノロジには、JPA 用の spring-boot-starter-data-jpa
、Mongodb 用の spring-boot-starter-data-mongodb
、その他さまざまなスターターがあります。まずは、@Entity
(英語) オブジェクトを処理するリポジトリインターフェースをいくつか作成します。
Spring Boot は、自動構成パッケージをスキャンして、Repository
(Javadoc) 実装の場所を決定します。より詳細な制御を行うには、Spring Data の @Enable … Repositories
アノテーションを使用します。
Spring Data の詳細については、Spring Data プロジェクトページを参照してください。
Spring 構成から @Entity 定義を分離する
Spring Boot は、自動構成パッケージをスキャンして、@Entity
(英語) 定義の場所を決定します。さらに制御するには、次の例に示すように、@EntityScan
(Javadoc) アノテーションを使用します。
Java
Kotlin
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.autoconfigure.domain.EntityScan;
import org.springframework.context.annotation.Configuration;
@Configuration(proxyBeanMethods = false)
@EnableAutoConfiguration
@EntityScan(basePackageClasses = City.class)
public class MyApplication {
// ...
}
import org.springframework.boot.autoconfigure.EnableAutoConfiguration
import org.springframework.boot.autoconfigure.domain.EntityScan
import org.springframework.context.annotation.Configuration
@Configuration(proxyBeanMethods = false)
@EnableAutoConfiguration
@EntityScan(basePackageClasses = [City::class])
class MyApplication {
// ...
}
スキャンされた @Entity 定義をフィルターする
ManagedClassNameFilter
(Javadoc) Bean を使用して @Entity
(英語) 定義をフィルタリングすることができます。これは、使用可能なエンティティのサブセットのみを考慮する必要があるテストで役立ちます。次の例では、com.example.app.customer
パッケージのエンティティのみが含まれます。
Java
Kotlin
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.orm.jpa.persistenceunit.ManagedClassNameFilter;
@Configuration(proxyBeanMethods = false)
public class MyEntityScanConfiguration {
@Bean
public ManagedClassNameFilter entityScanFilter() {
return (className) -> className.startsWith("com.example.app.customer.");
}
}
import org.springframework.context.annotation.Bean
import org.springframework.context.annotation.Configuration
import org.springframework.orm.jpa.persistenceunit.ManagedClassNameFilter
@Configuration(proxyBeanMethods = false)
class MyEntityScanConfiguration {
@Bean
fun entityScanFilter() : ManagedClassNameFilter {
return ManagedClassNameFilter { className ->
className.startsWith("com.example.app.customer.")
}
}
}
JPA プロパティの構成
Spring Data JPA は、ベンダーに依存しないいくつかの構成オプション(SQL ロギングのオプションなど)をすでに提供しており、Spring Boot はそれらのオプションと Hibernate のいくつかを外部構成プロパティとして公開しています。それらの一部はコンテキストに従って自動的に検出されるため、設定する必要はありません。
spring.jpa.hibernate.ddl-auto
は特殊なケースで、実行時の状況に応じてデフォルトが異なります。組み込みデータベースが使用され、スキーママネージャー (Liquibase や Flyway など) が DataSource
(標準 Javadoc) を処理していない場合、デフォルトは create-drop
になります。それ以外の場合は、デフォルトは none
になります。
使用するダイアレクトは JPA プロバイダーによって検出されます。ダイアレクトを自分で設定する場合は、spring.jpa.database-platform
プロパティを設定します。
設定する最も一般的なオプションを次の例に示します。
プロパティ
YAML
spring.jpa.hibernate.naming.physical-strategy=com.example.MyPhysicalNamingStrategy
spring.jpa.show-sql=true
spring:
jpa:
hibernate:
naming:
physical-strategy: "com.example.MyPhysicalNamingStrategy"
show-sql: true
さらに、ローカル EntityManagerFactory
(英語) が作成されるときに、spring.jpa.properties.*
内のすべてのプロパティが通常の JPA プロパティ (プレフィックスが削除された状態) として渡されます。
例: Hibernate のバッチサイズを設定する場合は、 |
Hibernate プロパティに高度なカスタマイズを適用する必要がある場合は、EntityManagerFactory (英語) を作成する前に呼び出される HibernatePropertiesCustomizer (Javadoc) Bean を登録することを検討してください。これは、自動構成によって適用されるものよりも優先されます。 |
Hibernate 命名戦略の構成
Hibernate は、2 つの異なる命名戦略 (英語) を使用して、オブジェクトモデルの名前を対応するデータベース名にマップします。物理および暗黙の戦略実装の完全修飾クラス名は、それぞれ spring.jpa.hibernate.naming.physical-strategy
プロパティと spring.jpa.hibernate.naming.implicit-strategy
プロパティを設定することで構成できます。または、アプリケーションコンテキストで ImplicitNamingStrategy
(英語) または PhysicalNamingStrategy
(英語) Bean が使用可能な場合、Hibernate はそれらを使用するように自動的に構成されます。
デフォルトでは、Spring Boot は物理命名戦略を CamelCaseToUnderscoresNamingStrategy
(英語) で構成します。この戦略を使用すると、すべてのドットがアンダースコアに置き換えられ、キャメルケースもアンダースコアに置き換えられます。また、デフォルトでは、すべてのテーブル名は小文字で生成されます。例: TelephoneNumber
エンティティは telephone_number
テーブルにマップされます。スキーマで大文字と小文字が混在する識別子が必要な場合は、次の例に示すように、カスタム CamelCaseToUnderscoresNamingStrategy
(英語) Bean を定義します。
Java
Kotlin
import org.hibernate.boot.model.naming.CamelCaseToUnderscoresNamingStrategy;
import org.hibernate.engine.jdbc.env.spi.JdbcEnvironment;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration(proxyBeanMethods = false)
public class MyHibernateConfiguration {
@Bean
public CamelCaseToUnderscoresNamingStrategy caseSensitivePhysicalNamingStrategy() {
return new CamelCaseToUnderscoresNamingStrategy() {
@Override
protected boolean isCaseInsensitive(JdbcEnvironment jdbcEnvironment) {
return false;
}
};
}
}
import org.hibernate.boot.model.naming.CamelCaseToUnderscoresNamingStrategy
import org.hibernate.engine.jdbc.env.spi.JdbcEnvironment
import org.springframework.context.annotation.Bean
import org.springframework.context.annotation.Configuration
@Configuration(proxyBeanMethods = false)
class MyHibernateConfiguration {
@Bean
fun caseSensitivePhysicalNamingStrategy(): CamelCaseToUnderscoresNamingStrategy {
return object : CamelCaseToUnderscoresNamingStrategy() {
override fun isCaseInsensitive(jdbcEnvironment: JdbcEnvironment): Boolean {
return false
}
}
}
}
代わりに Hibernate のデフォルトを使用する場合は、次のプロパティを設定します。
プロパティ
YAML
spring.jpa.hibernate.naming.physical-strategy=org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl
spring:
jpa:
hibernate:
naming:
physical-strategy: org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl
または、次の Bean を構成できます。
Java
Kotlin
import org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration(proxyBeanMethods = false)
class MyHibernateConfiguration {
@Bean
PhysicalNamingStrategyStandardImpl caseSensitivePhysicalNamingStrategy() {
return new PhysicalNamingStrategyStandardImpl();
}
}
import org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl
import org.springframework.context.annotation.Bean
import org.springframework.context.annotation.Configuration
@Configuration(proxyBeanMethods = false)
internal class MyHibernateConfiguration {
@Bean
fun caseSensitivePhysicalNamingStrategy(): PhysicalNamingStrategyStandardImpl {
return PhysicalNamingStrategyStandardImpl()
}
}
詳細については、HibernateJpaAutoConfiguration
[GitHub] (英語) および JpaBaseConfiguration
[GitHub] (英語) を参照してください。
Hibernate 2 次キャッシュを構成する
Hibernate 2 次キャッシュ (英語) は、さまざまなキャッシュプロバイダーに対して構成できます。キャッシュプロバイダーを再度検索するように Hibernate を構成するのではなく、可能な場合はコンテキストで利用可能なものを提供することをお勧めします。
JCache でこれを行うには、まずクラスパスで org.hibernate.orm:hibernate-jcache
が使用可能であることを確認します。次に、次の例に示すように、HibernatePropertiesCustomizer
(Javadoc) Bean を追加します。
Java
Kotlin
import org.hibernate.cache.jcache.ConfigSettings;
import org.springframework.boot.autoconfigure.orm.jpa.HibernatePropertiesCustomizer;
import org.springframework.cache.jcache.JCacheCacheManager;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration(proxyBeanMethods = false)
public class MyHibernateSecondLevelCacheConfiguration {
@Bean
public HibernatePropertiesCustomizer hibernateSecondLevelCacheCustomizer(JCacheCacheManager cacheManager) {
return (properties) -> properties.put(ConfigSettings.CACHE_MANAGER, cacheManager.getCacheManager());
}
}
import org.hibernate.cache.jcache.ConfigSettings
import org.springframework.boot.autoconfigure.orm.jpa.HibernatePropertiesCustomizer
import org.springframework.cache.jcache.JCacheCacheManager
import org.springframework.context.annotation.Bean
import org.springframework.context.annotation.Configuration
@Configuration(proxyBeanMethods = false)
class MyHibernateSecondLevelCacheConfiguration {
@Bean
fun hibernateSecondLevelCacheCustomizer(cacheManager: JCacheCacheManager): HibernatePropertiesCustomizer {
return HibernatePropertiesCustomizer { properties ->
properties[ConfigSettings.CACHE_MANAGER] = cacheManager.cacheManager
}
}
}
このカスタマイザーは、アプリケーションが使用するのと同じ CacheManager
(Javadoc) を使用するように Hibernate を構成します。別の CacheManager
(Javadoc) インスタンスを使用することもできます。詳細については、Hibernate ユーザーガイド (英語) を参照してください。
Hibernate コンポーネントでの依存性注入の使用
デフォルトでは、Spring Boot は BeanFactory
(Javadoc) を使用する BeanContainer
(英語) 実装を登録し、コンバーターとエンティティリスナーが通常の依存性注入を使用できるようにします。
hibernate.resource.beans.container
プロパティを削除または変更する HibernatePropertiesCustomizer
(Javadoc) を登録することにより、この動作を無効にしたり調整したりできます。
カスタム EntityManagerFactory を使用する
EntityManagerFactory
(英語) の構成を完全に制御するには、"entityManagerFactory" という名前の @Bean
(Javadoc) を追加する必要があります。Spring Boot の自動構成では、その型の Bean が存在する場合、エンティティマネージャーがオフになります。
LocalContainerEntityManagerFactoryBean (Javadoc) の Bean を自分で作成すると、自動構成された LocalContainerEntityManagerFactoryBean (Javadoc) の作成中に適用されたカスタマイズはすべて失われます。自動構成された EntityManagerFactoryBuilder (Javadoc) を使用して、JPA およびベンダープロパティを保持するようにしてください。これは、命名戦略や DDL モードなどの構成に spring.jpa.* プロパティに依存していた場合に特に重要です。 |
複数の EntityManagerFactories を使用する
複数のデータソースに対して JPA を使用する必要がある場合は、データソースごとに 1 つの EntityManagerFactory
(英語) が必要になる可能性があります。Spring ORM の LocalContainerEntityManagerFactoryBean
(Javadoc) を使用すると、ニーズに合わせて EntityManagerFactory
(英語) を構成できます。また、JpaProperties
(Javadoc) を再利用して、2 番目の EntityManagerFactory
(英語) の設定をバインドすることもできます。2 台目の DataSource
を構成する例を基にして、次の例に示すように 2 番目の EntityManagerFactory
(英語) を定義できます。
Java
Kotlin
import javax.sql.DataSource;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.autoconfigure.orm.jpa.JpaProperties;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.orm.jpa.EntityManagerFactoryBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.orm.jpa.JpaVendorAdapter;
import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
import org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter;
@Configuration(proxyBeanMethods = false)
public class MyAdditionalEntityManagerFactoryConfiguration {
@Qualifier("second")
@Bean(defaultCandidate = false)
@ConfigurationProperties("app.jpa")
public JpaProperties secondJpaProperties() {
return new JpaProperties();
}
@Qualifier("second")
@Bean(defaultCandidate = false)
public LocalContainerEntityManagerFactoryBean secondEntityManagerFactory(@Qualifier("second") DataSource dataSource,
@Qualifier("second") JpaProperties jpaProperties) {
EntityManagerFactoryBuilder builder = createEntityManagerFactoryBuilder(jpaProperties);
return builder.dataSource(dataSource).packages(Order.class).persistenceUnit("second").build();
}
private EntityManagerFactoryBuilder createEntityManagerFactoryBuilder(JpaProperties jpaProperties) {
JpaVendorAdapter jpaVendorAdapter = createJpaVendorAdapter(jpaProperties);
return new EntityManagerFactoryBuilder(jpaVendorAdapter, jpaProperties.getProperties(), null);
}
private JpaVendorAdapter createJpaVendorAdapter(JpaProperties jpaProperties) {
// ... map JPA properties as needed
return new HibernateJpaVendorAdapter();
}
}
import javax.sql.DataSource
import org.springframework.beans.factory.annotation.Qualifier
import org.springframework.boot.autoconfigure.orm.jpa.JpaProperties
import org.springframework.boot.context.properties.ConfigurationProperties
import org.springframework.boot.orm.jpa.EntityManagerFactoryBuilder
import org.springframework.context.annotation.Bean
import org.springframework.context.annotation.Configuration
import org.springframework.orm.jpa.JpaVendorAdapter
import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean
import org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter
@Configuration(proxyBeanMethods = false)
class MyAdditionalEntityManagerFactoryConfiguration {
@Qualifier("second")
@Bean(defaultCandidate = false)
@ConfigurationProperties("app.jpa")
fun secondJpaProperties(): JpaProperties {
return JpaProperties()
}
@Qualifier("second")
@Bean(defaultCandidate = false)
fun firstEntityManagerFactory(
@Qualifier("second") dataSource: DataSource,
@Qualifier("second") jpaProperties: JpaProperties
): LocalContainerEntityManagerFactoryBean {
val builder = createEntityManagerFactoryBuilder(jpaProperties)
return builder.dataSource(dataSource).packages(Order::class.java).persistenceUnit("second").build()
}
private fun createEntityManagerFactoryBuilder(jpaProperties: JpaProperties): EntityManagerFactoryBuilder {
val jpaVendorAdapter = createJpaVendorAdapter(jpaProperties)
return EntityManagerFactoryBuilder(jpaVendorAdapter, jpaProperties.properties, null)
}
private fun createJpaVendorAdapter(jpaProperties: JpaProperties): JpaVendorAdapter {
// ... map JPA properties as needed
return HibernateJpaVendorAdapter()
}
}
上記の例では、@Qualifier("second")
で修飾された DataSource
(標準 Javadoc) Bean を使用して EntityManagerFactory
(英語) を作成します。Order
と同じパッケージにあるエンティティをスキャンします。app.jpa
名前空間を使用して追加の JPA プロパティをマップすることができます。@Bean(defaultCandidate=false)
を使用すると、同じ型の自動構成された Bean に干渉することなく、secondJpaProperties
および secondEntityManagerFactory
Bean を定義できます。
Spring Framework リファレンスドキュメントではこの機能についてさらに詳しく説明しています。 |
JPA アクセスが必要な追加のデータソースに対しても同様の構成を提供する必要があります。全体像を完成させるには、各 EntityManagerFactory
(英語) に対しても JpaTransactionManager
(Javadoc) を構成する必要があります。または、両方にまたがる JTA トランザクションマネージャーを使用できる場合もあります。
Spring Data を使用する場合は、次の例に示すように、@EnableJpaRepositories
(Javadoc) をそれに応じて構成する必要があります。
Java
Kotlin
import org.springframework.context.annotation.Configuration;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
@Configuration(proxyBeanMethods = false)
@EnableJpaRepositories(basePackageClasses = Order.class, entityManagerFactoryRef = "entityManagerFactory")
public class OrderConfiguration {
}
import org.springframework.context.annotation.Configuration
import org.springframework.data.jpa.repository.config.EnableJpaRepositories
@Configuration(proxyBeanMethods = false)
@EnableJpaRepositories(basePackageClasses = [Order::class], entityManagerFactoryRef = "firstEntityManagerFactory")
class OrderConfiguration
Java
Kotlin
import org.springframework.context.annotation.Configuration;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
@Configuration(proxyBeanMethods = false)
@EnableJpaRepositories(basePackageClasses = Customer.class, entityManagerFactoryRef = "secondEntityManagerFactory")
public class CustomerConfiguration {
}
import org.springframework.context.annotation.Configuration
import org.springframework.data.jpa.repository.config.EnableJpaRepositories
@Configuration(proxyBeanMethods = false)
@EnableJpaRepositories(basePackageClasses = [Customer::class], entityManagerFactoryRef = "secondEntityManagerFactory")
class CustomerConfiguration
従来の persistence.xml ファイルを使用する
Spring Boot は、デフォルトでは META-INF/persistence.xml
を検索したり使用したりしません。従来の persistence.xml
を使用する場合は、型 LocalEntityManagerFactoryBean
(Javadoc) (ID は "entityManagerFactory" ) の独自の @Bean
(Javadoc) を定義し、そこに永続ユニット名を設定する必要があります。
デフォルト設定については、JpaBaseConfiguration
[GitHub] (英語) を参照してください。
Spring Data JPA および Mongo リポジトリを使用する
Spring Data JPA と Spring Data、Mongo はどちらも、Repository
(Javadoc) 実装を自動的に作成できます。クラスパスに両方が存在する場合は、Spring Boot にどのリポジトリを作成するかを伝えるために、追加の構成を行う必要がある場合があります。最も明示的にこれを行う方法は、標準の Spring Data @EnableJpaRepositories
(Javadoc) および @EnableMongoRepositories
(Javadoc) アノテーションを使用して、Repository
(Javadoc) インターフェースの場所を提供することです。
外部構成で自動構成されたリポジトリのオン / オフを切り替えるために使用できるフラグ (spring.data.*.repositories.enabled
および spring.data.*.repositories.type
) もあります。これを行うと、たとえば、Mongo リポジトリをオフにして、自動構成された MongoTemplate
(Javadoc) を引き続き使用する場合に役立ちます。
他の自動構成された Spring Data リポジトリ型 (Elasticsearch、Redis など) にも、同じ障害と同じ機能が存在します。これらを操作するには、アノテーションとフラグの名前を適宜変更します。
Spring Data の Web サポートのカスタマイズ
Spring Data は、Web アプリケーションでの Spring Data リポジトリの使用を簡素化する Web サポートを提供します。Spring Boot は、その構成をカスタマイズするための spring.data.web
名前空間のプロパティを提供します。Spring Data REST を使用している場合は、代わりに spring.data.rest
名前空間のプロパティを使用する必要があることに注意してください。
Spring Data リポジトリを REST エンドポイントとして公開する
アプリケーションで Spring MVC が有効になっている場合、Spring Data REST は Repository
(Javadoc) 実装を REST エンドポイントとして公開できます。
Spring Boot は、RepositoryRestConfiguration
(Javadoc) をカスタマイズする一連の有用なプロパティ(spring.data.rest
名前空間から)を公開します。追加のカスタマイズを提供する必要がある場合は、RepositoryRestConfigurer
(Javadoc) Bean を使用する必要があります。
カスタム RepositoryRestConfigurer (Javadoc) で順序を指定しない場合は、Spring Boot が内部で使用する順序の後に実行されます。順序を指定する必要がある場合は、0 より大きい値にしてください。 |
JPA によって使用されるコンポーネントを構成する
JPA が使用するコンポーネントを構成する場合は、JPA の前にコンポーネントが初期化されていることを確認する必要があります。コンポーネントが自動構成されると、Spring Boot がこれを処理します。例: Flyway が自動構成されると、Hibernate は Flyway に依存するように構成されるため、Hibernate がデータベースを使用する前に Flyway がデータベースを初期化する機会が得られます。
コンポーネントを自分で構成する場合は、必要な依存関係を設定する便利な方法として、EntityManagerFactoryDependsOnPostProcessor
(Javadoc) サブクラスを使用できます。例: Elasticsearch をインデックスマネージャーとして Hibernate 検索を使用する場合、次の例に示すように、すべての EntityManagerFactory
(英語) Bean を elasticsearchClient
Bean に依存するように構成する必要があります。
Java
Kotlin
import jakarta.persistence.EntityManagerFactory;
import org.springframework.boot.autoconfigure.orm.jpa.EntityManagerFactoryDependsOnPostProcessor;
import org.springframework.stereotype.Component;
/**
* {@link EntityManagerFactoryDependsOnPostProcessor} that ensures that
* {@link EntityManagerFactory} beans depend on the {@code elasticsearchClient} bean.
*/
@Component
public class ElasticsearchEntityManagerFactoryDependsOnPostProcessor
extends EntityManagerFactoryDependsOnPostProcessor {
public ElasticsearchEntityManagerFactoryDependsOnPostProcessor() {
super("elasticsearchClient");
}
}
import org.springframework.boot.autoconfigure.orm.jpa.EntityManagerFactoryDependsOnPostProcessor
import org.springframework.stereotype.Component
@Component
class ElasticsearchEntityManagerFactoryDependsOnPostProcessor :
EntityManagerFactoryDependsOnPostProcessor("elasticsearchClient")
2 つの DataSources で jOOQ を構成する
複数のデータソースで jOOQ を使用する必要がある場合は、それぞれに独自の DSLContext
(英語) を作成する必要があります。詳細については、JooqAutoConfiguration
[GitHub] (英語) を参照してください。
特に、JooqExceptionTranslator (Javadoc) と SpringTransactionProvider (Javadoc) を再利用すると、単一の DataSource (標準 Javadoc) で自動構成が行う機能と同様の機能を提供できます。 |