[[howto.data-access]] == Data Access Spring Boot includes a number of starters for working with data sources. This section answers questions related to doing so. [[howto.data-access.configure-custom-datasource]] === Configure a Custom DataSource To configure your own `DataSource`, define a `@Bean` of that type in your configuration. Spring Boot reuses your `DataSource` anywhere one is required, including database initialization. If you need to externalize some settings, you can bind your `DataSource` to the environment (see "`<>`"). The following example shows how to define a data source in a bean: include::code:custom/MyDataSourceConfiguration[] The following example shows how to define a data source by setting properties: [source,yaml,indent=0,subs="verbatim",configblocks] ---- app: datasource: url: "jdbc:h2:mem:mydb" username: "sa" pool-size: 30 ---- Assuming that `SomeDataSource` has regular JavaBean properties for the URL, the username, and the pool size, these settings are bound automatically before the `DataSource` is made available to other components. Spring Boot also provides a utility builder class, called `DataSourceBuilder`, that can be used to create one of the standard data sources (if it is on the classpath). The builder can detect the one to use based on what is available on the classpath. It also auto-detects the driver based on the JDBC URL. The following example shows how to create a data source by using a `DataSourceBuilder`: include::code:builder/MyDataSourceConfiguration[] To run an app with that `DataSource`, all you need is the connection information. Pool-specific settings can also be provided. Check the implementation that is going to be used at runtime for more details. The following example shows how to define a JDBC data source by setting properties: [source,yaml,indent=0,subs="verbatim",configblocks] ---- app: datasource: url: "jdbc:mysql://localhost/test" username: "dbuser" password: "dbpass" pool-size: 30 ---- However, there is a catch. Because the actual type of the connection pool is not exposed, no keys are generated in the metadata for your custom `DataSource` and no completion is available in your IDE (because the `DataSource` interface exposes no properties). Also, if you happen to have Hikari on the classpath, this basic setup does not work, because Hikari has no `url` property (but does have a `jdbcUrl` property). In that case, you must rewrite your configuration as follows: [source,yaml,indent=0,subs="verbatim",configblocks] ---- app: datasource: jdbc-url: "jdbc:mysql://localhost/test" username: "dbuser" password: "dbpass" pool-size: 30 ---- You can fix that by forcing the connection pool to use and return a dedicated implementation rather than `DataSource`. You cannot change the implementation at runtime, but the list of options will be explicit. The following example shows how create a `HikariDataSource` with `DataSourceBuilder`: include::code:simple/MyDataSourceConfiguration[] You can even go further by leveraging what `DataSourceProperties` does for you -- that is, by providing a default embedded database with a sensible username and password if no URL is provided. You can easily initialize a `DataSourceBuilder` from the state of any `DataSourceProperties` object, so you could also inject the DataSource that Spring Boot creates automatically. However, that would split your configuration into two namespaces: `url`, `username`, `password`, `type`, and `driver` on `spring.datasource` and the rest on your custom namespace (`app.datasource`). To avoid that, you can redefine a custom `DataSourceProperties` on your custom namespace, as shown in the following example: include::code:configurable/MyDataSourceConfiguration[] This setup puts you _in sync_ with what Spring Boot does for you by default, except that a dedicated connection pool is chosen (in code) and its settings are exposed in the `app.datasource.configuration` sub namespace. Because `DataSourceProperties` is taking care of the `url`/`jdbcUrl` translation for you, you can configure it as follows: [source,yaml,indent=0,subs="verbatim",configblocks] ---- app: datasource: url: "jdbc:mysql://localhost/test" username: "dbuser" password: "dbpass" configuration: maximum-pool-size: 30 ---- TIP: Spring Boot will expose Hikari-specific settings to `spring.datasource.hikari`. This example uses a more generic `configuration` sub namespace as the example does not support multiple datasource implementations. NOTE: Because your custom configuration chooses to go with Hikari, `app.datasource.type` has no effect. In practice, the builder is initialized with whatever value you might set there and then overridden by the call to `.type()`. See "`<>`" in the "`Spring Boot features`" section and the {spring-boot-autoconfigure-module-code}/jdbc/DataSourceAutoConfiguration.java[`DataSourceAutoConfiguration`] class for more details. [[howto.data-access.configure-two-datasources]] === Configure Two DataSources If you need to configure multiple data sources, you can apply the same tricks that are described in the previous section. You must, however, mark one of the `DataSource` instances as `@Primary`, because various auto-configurations down the road expect to be able to get one by type. If you create your own `DataSource`, the auto-configuration backs off. In the following example, we provide the _exact_ same feature set as the auto-configuration provides on the primary data source: include::code:MyDataSourcesConfiguration[] TIP: `firstDataSourceProperties` has to be flagged as `@Primary` so that the database initializer feature uses your copy (if you use the initializer). Both data sources are also bound for advanced customizations. For instance, you could configure them as follows: [source,yaml,indent=0,subs="verbatim",configblocks] ---- app: datasource: first: url: "jdbc:mysql://localhost/first" username: "dbuser" password: "dbpass" configuration: maximum-pool-size: 30 second: url: "jdbc:mysql://localhost/second" username: "dbuser" password: "dbpass" max-total: 30 ---- You can apply the same concept to the secondary `DataSource` as well, as shown in the following example: include::code:MyCompleteDataSourcesConfiguration[] The preceding example configures two data sources on custom namespaces with the same logic as Spring Boot would use in auto-configuration. Note that each `configuration` sub namespace provides advanced settings based on the chosen implementation. [[howto.data-access.spring-data-repositories]] === Use Spring Data Repositories Spring Data can create implementations of `@Repository` interfaces of various flavors. Spring Boot handles all of that for you, as long as those `@Repositories` are included in the same package (or a sub-package) of your `@EnableAutoConfiguration` class. For many applications, all you need is to put the right Spring Data dependencies on your classpath. There is a `spring-boot-starter-data-jpa` for JPA, `spring-boot-starter-data-mongodb` for Mongodb, and various other starters for supported technologies. To get started, create some repository interfaces to handle your `@Entity` objects. Spring Boot tries to guess the location of your `@Repository` definitions, based on the `@EnableAutoConfiguration` it finds. To get more control, use the `@EnableJpaRepositories` annotation (from Spring Data JPA). For more about Spring Data, see the {spring-data}[Spring Data project page]. [[howto.data-access.separate-entity-definitions-from-spring-configuration]] === Separate @Entity Definitions from Spring Configuration Spring Boot tries to guess the location of your `@Entity` definitions, based on the `@EnableAutoConfiguration` it finds. To get more control, you can use the `@EntityScan` annotation, as shown in the following example: include::code:MyApplication[] [[howto.data-access.jpa-properties]] === Configure JPA Properties Spring Data JPA already provides some vendor-independent configuration options (such as those for SQL logging), and Spring Boot exposes those options and a few more for Hibernate as external configuration properties. Some of them are automatically detected according to the context so you should not have to set them. The `spring.jpa.hibernate.ddl-auto` is a special case, because, depending on runtime conditions, it has different defaults. If an embedded database is used and no schema manager (such as Liquibase or Flyway) is handling the `DataSource`, it defaults to `create-drop`. In all other cases, it defaults to `none`. The dialect to use is detected by the JPA provider. If you prefer to set the dialect yourself, set the configprop:spring.jpa.database-platform[] property. The most common options to set are shown in the following example: [source,yaml,indent=0,subs="verbatim",configprops,configblocks] ---- spring: jpa: hibernate: naming: physical-strategy: "com.example.MyPhysicalNamingStrategy" show-sql: true ---- In addition, all properties in `+spring.jpa.properties.*+` are passed through as normal JPA properties (with the prefix stripped) when the local `EntityManagerFactory` is created. [WARNING] ==== You need to ensure that names defined under `+spring.jpa.properties.*+` exactly match those expected by your JPA provider. Spring Boot will not attempt any kind of relaxed binding for these entries. For example, if you want to configure Hibernate's batch size you must use `+spring.jpa.properties.hibernate.jdbc.batch_size+`. If you use other forms, such as `batchSize` or `batch-size`, Hibernate will not apply the setting. ==== TIP: If you need to apply advanced customization to Hibernate properties, consider registering a `HibernatePropertiesCustomizer` bean that will be invoked prior to creating the `EntityManagerFactory`. This takes precedence to anything that is applied by the auto-configuration. [[howto.data-access.configure-hibernate-naming-strategy]] === Configure Hibernate Naming Strategy Hibernate uses {hibernate-docs}#naming[two different naming strategies] to map names from the object model to the corresponding database names. The fully qualified class name of the physical and the implicit strategy implementations can be configured by setting the `spring.jpa.hibernate.naming.physical-strategy` and `spring.jpa.hibernate.naming.implicit-strategy` properties, respectively. Alternatively, if `ImplicitNamingStrategy` or `PhysicalNamingStrategy` beans are available in the application context, Hibernate will be automatically configured to use them. By default, Spring Boot configures the physical naming strategy with `CamelCaseToUnderscoresNamingStrategy`. Using this strategy, all dots are replaced by underscores and camel casing is replaced by underscores as well. Additionally, by default, all table names are generated in lower case. For example, a `TelephoneNumber` entity is mapped to the `telephone_number` table. If your schema requires mixed-case identifiers, define a custom `CamelCaseToUnderscoresNamingStrategy` bean, as shown in the following example: include::code:spring/MyHibernateConfiguration[] If you prefer to use Hibernate 5's default instead, set the following property: [indent=0,properties,subs="verbatim"] ---- spring.jpa.hibernate.naming.physical-strategy=org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl ---- Alternatively, you can configure the following bean: include::code:standard/MyHibernateConfiguration[] See {spring-boot-autoconfigure-module-code}/orm/jpa/HibernateJpaAutoConfiguration.java[`HibernateJpaAutoConfiguration`] and {spring-boot-autoconfigure-module-code}/orm/jpa/JpaBaseConfiguration.java[`JpaBaseConfiguration`] for more details. [[howto.data-access.configure-hibernate-second-level-caching]] === Configure Hibernate Second-Level Caching Hibernate {hibernate-docs}#caching[second-level cache] can be configured for a range of cache providers. Rather than configuring Hibernate to lookup the cache provider again, it is better to provide the one that is available in the context whenever possible. To do this with JCache, first make sure that `org.hibernate:hibernate-jcache` is available on the classpath. Then, add a `HibernatePropertiesCustomizer` bean as shown in the following example: include::code:MyHibernateSecondLevelCacheConfiguration[] This customizer will configure Hibernate to use the same `CacheManager` as the one that the application uses. It is also possible to use separate `CacheManager` instances. For details, see {hibernate-docs}#caching-provider-jcache[the Hibernate user guide]. [[howto.data-access.dependency-injection-in-hibernate-components]] === Use Dependency Injection in Hibernate Components By default, Spring Boot registers a `BeanContainer` implementation that uses the `BeanFactory` so that converters and entity listeners can use regular dependency injection. You can disable or tune this behavior by registering a `HibernatePropertiesCustomizer` that removes or changes the `hibernate.resource.beans.container` property. [[howto.data-access.use-custom-entity-manager]] === Use a Custom EntityManagerFactory To take full control of the configuration of the `EntityManagerFactory`, you need to add a `@Bean` named '`entityManagerFactory`'. Spring Boot auto-configuration switches off its entity manager in the presence of a bean of that type. [[howto.data-access.use-multiple-entity-managers]] [[howto.data-access.use-multiple-entity-managers]] === Using Multiple EntityManagerFactories If you need to use JPA against multiple data sources, you likely need one `EntityManagerFactory` per data source. The `LocalContainerEntityManagerFactoryBean` from Spring ORM allows you to configure an `EntityManagerFactory` for your needs. You can also reuse `JpaProperties` to bind settings for each `EntityManagerFactory`, as shown in the following example: include::code:MyEntityManagerFactoryConfiguration[] The example above creates an `EntityManagerFactory` using a `DataSource` bean named `firstDataSource`. It scans entities located in the same package as `Order`. It is possible to map additional JPA properties using the `app.first.jpa` namespace. NOTE: When you create a bean for `LocalContainerEntityManagerFactoryBean` yourself, any customization that was applied during the creation of the auto-configured `LocalContainerEntityManagerFactoryBean` is lost. For example, in case of Hibernate, any properties under the `spring.jpa.hibernate` prefix will not be automatically applied to your `LocalContainerEntityManagerFactoryBean`. If you were relying on these properties for configuring things like the naming strategy or the DDL mode, you will need to explicitly configure that when creating the `LocalContainerEntityManagerFactoryBean` bean. You should provide a similar configuration for any additional data sources for which you need JPA access. To complete the picture, you need to configure a `JpaTransactionManager` for each `EntityManagerFactory` as well. Alternatively, you might be able to use a JTA transaction manager that spans both. If you use Spring Data, you need to configure `@EnableJpaRepositories` accordingly, as shown in the following examples: include::code:OrderConfiguration[] include::code:CustomerConfiguration[] [[howto.data-access.use-traditional-persistence-xml]] === Use a Traditional persistence.xml File Spring Boot will not search for or use a `META-INF/persistence.xml` by default. If you prefer to use a traditional `persistence.xml`, you need to define your own `@Bean` of type `LocalEntityManagerFactoryBean` (with an ID of '`entityManagerFactory`') and set the persistence unit name there. See {spring-boot-autoconfigure-module-code}/orm/jpa/JpaBaseConfiguration.java[`JpaBaseConfiguration`] for the default settings. [[howto.data-access.use-spring-data-jpa-and-mongo-repositories]] === Use Spring Data JPA and Mongo Repositories Spring Data JPA and Spring Data Mongo can both automatically create `Repository` implementations for you. If they are both present on the classpath, you might have to do some extra configuration to tell Spring Boot which repositories to create. The most explicit way to do that is to use the standard Spring Data `+@EnableJpaRepositories+` and `+@EnableMongoRepositories+` annotations and provide the location of your `Repository` interfaces. There are also flags (`+spring.data.*.repositories.enabled+` and `+spring.data.*.repositories.type+`) that you can use to switch the auto-configured repositories on and off in external configuration. Doing so is useful, for instance, in case you want to switch off the Mongo repositories and still use the auto-configured `MongoTemplate`. The same obstacle and the same features exist for other auto-configured Spring Data repository types (Elasticsearch, Solr, and others). To work with them, change the names of the annotations and flags accordingly. [[howto.data-access.customize-spring-data-web-support]] === Customize Spring Data's Web Support Spring Data provides web support that simplifies the use of Spring Data repositories in a web application. Spring Boot provides properties in the `spring.data.web` namespace for customizing its configuration. Note that if you are using Spring Data REST, you must use the properties in the `spring.data.rest` namespace instead. [[howto.data-access.exposing-spring-data-repositories-as-rest]] === Expose Spring Data Repositories as REST Endpoint Spring Data REST can expose the `Repository` implementations as REST endpoints for you, provided Spring MVC has been enabled for the application. Spring Boot exposes a set of useful properties (from the `spring.data.rest` namespace) that customize the {spring-data-rest-api}/core/config/RepositoryRestConfiguration.html[`RepositoryRestConfiguration`]. If you need to provide additional customization, you should use a {spring-data-rest-api}/webmvc/config/RepositoryRestConfigurer.html[`RepositoryRestConfigurer`] bean. NOTE: If you do not specify any order on your custom `RepositoryRestConfigurer`, it runs after the one Spring Boot uses internally. If you need to specify an order, make sure it is higher than 0. [[howto.data-access.configure-a-component-that-is-used-by-jpa]] === Configure a Component that is Used by JPA If you want to configure a component that JPA uses, then you need to ensure that the component is initialized before JPA. When the component is auto-configured, Spring Boot takes care of this for you. For example, when Flyway is auto-configured, Hibernate is configured to depend upon Flyway so that Flyway has a chance to initialize the database before Hibernate tries to use it. If you are configuring a component yourself, you can use an `EntityManagerFactoryDependsOnPostProcessor` subclass as a convenient way of setting up the necessary dependencies. For example, if you use Hibernate Search with Elasticsearch as its index manager, any `EntityManagerFactory` beans must be configured to depend on the `elasticsearchClient` bean, as shown in the following example: include::code:ElasticsearchEntityManagerFactoryDependsOnPostProcessor[] [[howto.data-access.configure-jooq-with-multiple-datasources]] === Configure jOOQ with Two DataSources If you need to use jOOQ with multiple data sources, you should create your own `DSLContext` for each one. See {spring-boot-autoconfigure-module-code}/jooq/JooqAutoConfiguration.java[JooqAutoConfiguration] for more details. TIP: In particular, `JooqExceptionTranslator` and `SpringTransactionProvider` can be reused to provide similar features to what the auto-configuration does with a single `DataSource`.