Merge pull request #22610 from scordio
* pr/22610: Polish "Add auto-configuration for Spring Data Envers" Add auto-configuration for Spring Data Envers Closes gh-22610
This commit is contained in:
		
						commit
						fbbfe6ac86
					
				| 
						 | 
				
			
			@ -112,6 +112,7 @@ dependencies {
 | 
			
		|||
	optional("org.springframework:spring-webmvc")
 | 
			
		||||
	optional("org.springframework.batch:spring-batch-core")
 | 
			
		||||
	optional("org.springframework.data:spring-data-couchbase")
 | 
			
		||||
	optional("org.springframework.data:spring-data-envers")
 | 
			
		||||
	optional("org.springframework.data:spring-data-jpa")
 | 
			
		||||
	optional("org.springframework.data:spring-data-rest-webmvc")
 | 
			
		||||
	optional("org.springframework.data:spring-data-cassandra")
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -0,0 +1,41 @@
 | 
			
		|||
/*
 | 
			
		||||
 * Copyright 2012-2021 the original author or authors.
 | 
			
		||||
 *
 | 
			
		||||
 * Licensed under the Apache License, Version 2.0 (the "License");
 | 
			
		||||
 * you may not use this file except in compliance with the License.
 | 
			
		||||
 * You may obtain a copy of the License at
 | 
			
		||||
 *
 | 
			
		||||
 *      https://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
 *
 | 
			
		||||
 * Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
 * distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
 * See the License for the specific language governing permissions and
 | 
			
		||||
 * limitations under the License.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
package org.springframework.boot.autoconfigure.data.jpa;
 | 
			
		||||
 | 
			
		||||
import org.springframework.context.annotation.ImportBeanDefinitionRegistrar;
 | 
			
		||||
import org.springframework.data.envers.repository.support.EnversRevisionRepositoryFactoryBean;
 | 
			
		||||
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * {@link ImportBeanDefinitionRegistrar} used to auto-configure Spring Data Envers
 | 
			
		||||
 * Repositories.
 | 
			
		||||
 *
 | 
			
		||||
 * @author Stefano Cordio
 | 
			
		||||
 */
 | 
			
		||||
class EnversRevisionRepositoriesRegistrar extends JpaRepositoriesRegistrar {
 | 
			
		||||
 | 
			
		||||
	@Override
 | 
			
		||||
	protected Class<?> getConfiguration() {
 | 
			
		||||
		return EnableJpaRepositoriesConfiguration.class;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	@EnableJpaRepositories(repositoryFactoryBeanClass = EnversRevisionRepositoryFactoryBean.class)
 | 
			
		||||
	private static class EnableJpaRepositoriesConfiguration {
 | 
			
		||||
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -27,6 +27,7 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
 | 
			
		|||
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
 | 
			
		||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
 | 
			
		||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
 | 
			
		||||
import org.springframework.boot.autoconfigure.data.jpa.JpaRepositoriesAutoConfiguration.JpaRepositoriesImportSelector;
 | 
			
		||||
import org.springframework.boot.autoconfigure.orm.jpa.EntityManagerFactoryBuilderCustomizer;
 | 
			
		||||
import org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration;
 | 
			
		||||
import org.springframework.boot.autoconfigure.task.TaskExecutionAutoConfiguration;
 | 
			
		||||
| 
						 | 
				
			
			@ -34,11 +35,17 @@ import org.springframework.context.annotation.Bean;
 | 
			
		|||
import org.springframework.context.annotation.Conditional;
 | 
			
		||||
import org.springframework.context.annotation.Configuration;
 | 
			
		||||
import org.springframework.context.annotation.Import;
 | 
			
		||||
import org.springframework.context.annotation.ImportSelector;
 | 
			
		||||
import org.springframework.core.task.AsyncTaskExecutor;
 | 
			
		||||
import org.springframework.core.type.AnnotationMetadata;
 | 
			
		||||
import org.springframework.data.envers.repository.config.EnableEnversRepositories;
 | 
			
		||||
import org.springframework.data.envers.repository.support.EnversRevisionRepositoryFactoryBean;
 | 
			
		||||
import org.springframework.data.jpa.repository.JpaRepository;
 | 
			
		||||
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
 | 
			
		||||
import org.springframework.data.jpa.repository.config.JpaRepositoryConfigExtension;
 | 
			
		||||
import org.springframework.data.jpa.repository.support.JpaRepositoryFactoryBean;
 | 
			
		||||
import org.springframework.data.repository.history.RevisionRepository;
 | 
			
		||||
import org.springframework.util.ClassUtils;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * {@link EnableAutoConfiguration Auto-configuration} for Spring Data's JPA Repositories.
 | 
			
		||||
| 
						 | 
				
			
			@ -50,11 +57,17 @@ import org.springframework.data.jpa.repository.support.JpaRepositoryFactoryBean;
 | 
			
		|||
 * Once in effect, the auto-configuration is the equivalent of enabling JPA repositories
 | 
			
		||||
 * using the {@link EnableJpaRepositories @EnableJpaRepositories} annotation.
 | 
			
		||||
 * <p>
 | 
			
		||||
 * In case {@link EnableEnversRepositories} is on the classpath,
 | 
			
		||||
 * {@link EnversRevisionRepositoryFactoryBean} is used instead of
 | 
			
		||||
 * {@link JpaRepositoryFactoryBean} to support {@link RevisionRepository} with Hibernate
 | 
			
		||||
 * Envers.
 | 
			
		||||
 * <p>
 | 
			
		||||
 * This configuration class will activate <em>after</em> the Hibernate auto-configuration.
 | 
			
		||||
 *
 | 
			
		||||
 * @author Phillip Webb
 | 
			
		||||
 * @author Josh Long
 | 
			
		||||
 * @author Scott Frederick
 | 
			
		||||
 * @author Stefano Cordio
 | 
			
		||||
 * @since 1.0.0
 | 
			
		||||
 * @see EnableJpaRepositories
 | 
			
		||||
 */
 | 
			
		||||
| 
						 | 
				
			
			@ -64,7 +77,7 @@ import org.springframework.data.jpa.repository.support.JpaRepositoryFactoryBean;
 | 
			
		|||
@ConditionalOnMissingBean({ JpaRepositoryFactoryBean.class, JpaRepositoryConfigExtension.class })
 | 
			
		||||
@ConditionalOnProperty(prefix = "spring.data.jpa.repositories", name = "enabled", havingValue = "true",
 | 
			
		||||
		matchIfMissing = true)
 | 
			
		||||
@Import(JpaRepositoriesRegistrar.class)
 | 
			
		||||
@Import(JpaRepositoriesImportSelector.class)
 | 
			
		||||
@AutoConfigureAfter({ HibernateJpaAutoConfiguration.class, TaskExecutionAutoConfiguration.class })
 | 
			
		||||
public class JpaRepositoriesAutoConfiguration {
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -106,4 +119,22 @@ public class JpaRepositoriesAutoConfiguration {
 | 
			
		|||
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	static class JpaRepositoriesImportSelector implements ImportSelector {
 | 
			
		||||
 | 
			
		||||
		private static final boolean ENVERS_AVAILABLE = ClassUtils.isPresent(
 | 
			
		||||
				"org.springframework.data.envers.repository.config.EnableEnversRepositories",
 | 
			
		||||
				JpaRepositoriesImportSelector.class.getClassLoader());
 | 
			
		||||
 | 
			
		||||
		@Override
 | 
			
		||||
		public String[] selectImports(AnnotationMetadata importingClassMetadata) {
 | 
			
		||||
			return new String[] { determineImport() };
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		private String determineImport() {
 | 
			
		||||
			return ENVERS_AVAILABLE ? EnversRevisionRepositoriesRegistrar.class.getName()
 | 
			
		||||
					: JpaRepositoriesRegistrar.class.getName();
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -0,0 +1,187 @@
 | 
			
		|||
/*
 | 
			
		||||
 * Copyright 2012-2021 the original author or authors.
 | 
			
		||||
 *
 | 
			
		||||
 * Licensed under the Apache License, Version 2.0 (the "License");
 | 
			
		||||
 * you may not use this file except in compliance with the License.
 | 
			
		||||
 * You may obtain a copy of the License at
 | 
			
		||||
 *
 | 
			
		||||
 *      https://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
 *
 | 
			
		||||
 * Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
 * distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
 * See the License for the specific language governing permissions and
 | 
			
		||||
 * limitations under the License.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
package org.springframework.boot.autoconfigure.data.jpa;
 | 
			
		||||
 | 
			
		||||
import javax.persistence.EntityManagerFactory;
 | 
			
		||||
 | 
			
		||||
import org.junit.jupiter.api.Test;
 | 
			
		||||
 | 
			
		||||
import org.springframework.boot.autoconfigure.AutoConfigurations;
 | 
			
		||||
import org.springframework.boot.autoconfigure.TestAutoConfigurationPackage;
 | 
			
		||||
import org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoConfiguration;
 | 
			
		||||
import org.springframework.boot.autoconfigure.data.alt.elasticsearch.CityElasticsearchDbRepository;
 | 
			
		||||
import org.springframework.boot.autoconfigure.data.alt.jpa.CityJpaRepository;
 | 
			
		||||
import org.springframework.boot.autoconfigure.data.alt.mongo.CityMongoDbRepository;
 | 
			
		||||
import org.springframework.boot.autoconfigure.data.jpa.city.City;
 | 
			
		||||
import org.springframework.boot.autoconfigure.data.jpa.city.CityRepository;
 | 
			
		||||
import org.springframework.boot.autoconfigure.data.jpa.country.Country;
 | 
			
		||||
import org.springframework.boot.autoconfigure.jdbc.EmbeddedDataSourceConfiguration;
 | 
			
		||||
import org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration;
 | 
			
		||||
import org.springframework.boot.autoconfigure.task.TaskExecutionAutoConfiguration;
 | 
			
		||||
import org.springframework.boot.autoconfigure.task.TaskSchedulingAutoConfiguration;
 | 
			
		||||
import org.springframework.boot.test.context.runner.ApplicationContextRunner;
 | 
			
		||||
import org.springframework.context.annotation.Bean;
 | 
			
		||||
import org.springframework.context.annotation.ComponentScan.Filter;
 | 
			
		||||
import org.springframework.context.annotation.Configuration;
 | 
			
		||||
import org.springframework.context.annotation.FilterType;
 | 
			
		||||
import org.springframework.context.annotation.Import;
 | 
			
		||||
import org.springframework.core.task.SimpleAsyncTaskExecutor;
 | 
			
		||||
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
 | 
			
		||||
import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
 | 
			
		||||
import org.springframework.scheduling.annotation.EnableScheduling;
 | 
			
		||||
import org.springframework.transaction.PlatformTransactionManager;
 | 
			
		||||
 | 
			
		||||
import static org.assertj.core.api.Assertions.assertThat;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Base class for {@link JpaRepositoriesAutoConfiguration} tests.
 | 
			
		||||
 *
 | 
			
		||||
 * @author Dave Syer
 | 
			
		||||
 * @author Oliver Gierke
 | 
			
		||||
 * @author Scott Frederick
 | 
			
		||||
 * @author Stefano Cordio
 | 
			
		||||
 */
 | 
			
		||||
abstract class AbstractJpaRepositoriesAutoConfigurationTests {
 | 
			
		||||
 | 
			
		||||
	final ApplicationContextRunner contextRunner = new ApplicationContextRunner()
 | 
			
		||||
			.withConfiguration(AutoConfigurations.of(HibernateJpaAutoConfiguration.class,
 | 
			
		||||
					JpaRepositoriesAutoConfiguration.class, PropertyPlaceholderAutoConfiguration.class))
 | 
			
		||||
			.withUserConfiguration(EmbeddedDataSourceConfiguration.class);
 | 
			
		||||
 | 
			
		||||
	@Test
 | 
			
		||||
	void testDefaultRepositoryConfiguration() {
 | 
			
		||||
		this.contextRunner.withUserConfiguration(TestConfiguration.class).run((context) -> {
 | 
			
		||||
			assertThat(context).hasSingleBean(CityRepository.class);
 | 
			
		||||
			assertThat(context).hasSingleBean(PlatformTransactionManager.class);
 | 
			
		||||
			assertThat(context).hasSingleBean(EntityManagerFactory.class);
 | 
			
		||||
			assertThat(context.getBean(LocalContainerEntityManagerFactoryBean.class).getBootstrapExecutor()).isNull();
 | 
			
		||||
		});
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	@Test
 | 
			
		||||
	void testOverrideRepositoryConfiguration() {
 | 
			
		||||
		this.contextRunner.withUserConfiguration(CustomConfiguration.class).run((context) -> {
 | 
			
		||||
			assertThat(context).hasSingleBean(CityJpaRepository.class);
 | 
			
		||||
			assertThat(context).hasSingleBean(PlatformTransactionManager.class);
 | 
			
		||||
			assertThat(context).hasSingleBean(EntityManagerFactory.class);
 | 
			
		||||
		});
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	@Test
 | 
			
		||||
	void autoConfigurationShouldNotKickInEvenIfManualConfigDidNotCreateAnyRepositories() {
 | 
			
		||||
		this.contextRunner.withUserConfiguration(SortOfInvalidCustomConfiguration.class)
 | 
			
		||||
				.run((context) -> assertThat(context).doesNotHaveBean(CityRepository.class));
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	@Test
 | 
			
		||||
	void whenBootstrapModeIsLazyWithMultipleAsyncExecutorBootstrapExecutorIsConfigured() {
 | 
			
		||||
		this.contextRunner.withUserConfiguration(MultipleAsyncTaskExecutorConfiguration.class)
 | 
			
		||||
				.withConfiguration(AutoConfigurations.of(TaskExecutionAutoConfiguration.class,
 | 
			
		||||
						TaskSchedulingAutoConfiguration.class))
 | 
			
		||||
				.withPropertyValues("spring.data.jpa.repositories.bootstrap-mode=lazy")
 | 
			
		||||
				.run((context) -> assertThat(
 | 
			
		||||
						context.getBean(LocalContainerEntityManagerFactoryBean.class).getBootstrapExecutor())
 | 
			
		||||
								.isEqualTo(context.getBean("applicationTaskExecutor")));
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	@Test
 | 
			
		||||
	void whenBootstrapModeIsLazyWithSingleAsyncExecutorBootstrapExecutorIsConfigured() {
 | 
			
		||||
		this.contextRunner.withUserConfiguration(SingleAsyncTaskExecutorConfiguration.class)
 | 
			
		||||
				.withPropertyValues("spring.data.jpa.repositories.bootstrap-mode=lazy")
 | 
			
		||||
				.run((context) -> assertThat(
 | 
			
		||||
						context.getBean(LocalContainerEntityManagerFactoryBean.class).getBootstrapExecutor())
 | 
			
		||||
								.isEqualTo(context.getBean("testAsyncTaskExecutor")));
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	@Test
 | 
			
		||||
	void whenBootstrapModeIsDeferredBootstrapExecutorIsConfigured() {
 | 
			
		||||
		this.contextRunner.withUserConfiguration(MultipleAsyncTaskExecutorConfiguration.class)
 | 
			
		||||
				.withConfiguration(AutoConfigurations.of(TaskExecutionAutoConfiguration.class,
 | 
			
		||||
						TaskSchedulingAutoConfiguration.class))
 | 
			
		||||
				.withPropertyValues("spring.data.jpa.repositories.bootstrap-mode=deferred")
 | 
			
		||||
				.run((context) -> assertThat(
 | 
			
		||||
						context.getBean(LocalContainerEntityManagerFactoryBean.class).getBootstrapExecutor())
 | 
			
		||||
								.isEqualTo(context.getBean("applicationTaskExecutor")));
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	@Test
 | 
			
		||||
	void whenBootstrapModeIsDefaultBootstrapExecutorIsNotConfigured() {
 | 
			
		||||
		this.contextRunner.withUserConfiguration(MultipleAsyncTaskExecutorConfiguration.class)
 | 
			
		||||
				.withConfiguration(AutoConfigurations.of(TaskExecutionAutoConfiguration.class,
 | 
			
		||||
						TaskSchedulingAutoConfiguration.class))
 | 
			
		||||
				.withPropertyValues("spring.data.jpa.repositories.bootstrap-mode=default").run((context) -> assertThat(
 | 
			
		||||
						context.getBean(LocalContainerEntityManagerFactoryBean.class).getBootstrapExecutor()).isNull());
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	@Test
 | 
			
		||||
	void bootstrapModeIsDefaultByDefault() {
 | 
			
		||||
		this.contextRunner.withUserConfiguration(MultipleAsyncTaskExecutorConfiguration.class)
 | 
			
		||||
				.withConfiguration(AutoConfigurations.of(TaskExecutionAutoConfiguration.class,
 | 
			
		||||
						TaskSchedulingAutoConfiguration.class))
 | 
			
		||||
				.run((context) -> assertThat(
 | 
			
		||||
						context.getBean(LocalContainerEntityManagerFactoryBean.class).getBootstrapExecutor()).isNull());
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	@Configuration(proxyBeanMethods = false)
 | 
			
		||||
	@EnableScheduling
 | 
			
		||||
	@Import(TestConfiguration.class)
 | 
			
		||||
	static class MultipleAsyncTaskExecutorConfiguration {
 | 
			
		||||
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	@Configuration(proxyBeanMethods = false)
 | 
			
		||||
	@Import(TestConfiguration.class)
 | 
			
		||||
	static class SingleAsyncTaskExecutorConfiguration {
 | 
			
		||||
 | 
			
		||||
		@Bean
 | 
			
		||||
		SimpleAsyncTaskExecutor testAsyncTaskExecutor() {
 | 
			
		||||
			return new SimpleAsyncTaskExecutor();
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	@Configuration(proxyBeanMethods = false)
 | 
			
		||||
	@TestAutoConfigurationPackage(City.class)
 | 
			
		||||
	static class TestConfiguration {
 | 
			
		||||
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	@Configuration(proxyBeanMethods = false)
 | 
			
		||||
	@EnableJpaRepositories(
 | 
			
		||||
			basePackageClasses = org.springframework.boot.autoconfigure.data.alt.jpa.CityJpaRepository.class,
 | 
			
		||||
			excludeFilters = { @Filter(type = FilterType.ASSIGNABLE_TYPE, value = CityMongoDbRepository.class),
 | 
			
		||||
					@Filter(type = FilterType.ASSIGNABLE_TYPE, value = CityElasticsearchDbRepository.class) })
 | 
			
		||||
	@TestAutoConfigurationPackage(City.class)
 | 
			
		||||
	static class CustomConfiguration {
 | 
			
		||||
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	@Configuration(proxyBeanMethods = false)
 | 
			
		||||
	// To not find any repositories
 | 
			
		||||
	@EnableJpaRepositories("foo.bar")
 | 
			
		||||
	@TestAutoConfigurationPackage(City.class)
 | 
			
		||||
	static class SortOfInvalidCustomConfiguration {
 | 
			
		||||
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	@Configuration(proxyBeanMethods = false)
 | 
			
		||||
	@TestAutoConfigurationPackage(Country.class)
 | 
			
		||||
	static class RevisionRepositoryConfiguration {
 | 
			
		||||
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,39 @@
 | 
			
		|||
/*
 | 
			
		||||
 * Copyright 2012-2021 the original author or authors.
 | 
			
		||||
 *
 | 
			
		||||
 * Licensed under the Apache License, Version 2.0 (the "License");
 | 
			
		||||
 * you may not use this file except in compliance with the License.
 | 
			
		||||
 * You may obtain a copy of the License at
 | 
			
		||||
 *
 | 
			
		||||
 *      https://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
 *
 | 
			
		||||
 * Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
 * distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
 * See the License for the specific language governing permissions and
 | 
			
		||||
 * limitations under the License.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
package org.springframework.boot.autoconfigure.data.jpa;
 | 
			
		||||
 | 
			
		||||
import org.junit.jupiter.api.Test;
 | 
			
		||||
 | 
			
		||||
import org.springframework.boot.autoconfigure.data.jpa.country.CountryRepository;
 | 
			
		||||
 | 
			
		||||
import static org.assertj.core.api.Assertions.assertThat;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Tests for {@link JpaRepositoriesAutoConfiguration} with Spring Data Envers on the
 | 
			
		||||
 * classpath.
 | 
			
		||||
 *
 | 
			
		||||
 * @author Stefano Cordio
 | 
			
		||||
 */
 | 
			
		||||
class EnversRevisionRepositoriesAutoConfigurationTests extends AbstractJpaRepositoriesAutoConfigurationTests {
 | 
			
		||||
 | 
			
		||||
	@Test
 | 
			
		||||
	void autoConfigurationShouldSucceedWithRevisionRepository() {
 | 
			
		||||
		this.contextRunner.withUserConfiguration(RevisionRepositoryConfiguration.class)
 | 
			
		||||
				.run((context) -> assertThat(context).hasSingleBean(CountryRepository.class));
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -16,164 +16,26 @@
 | 
			
		|||
 | 
			
		||||
package org.springframework.boot.autoconfigure.data.jpa;
 | 
			
		||||
 | 
			
		||||
import javax.persistence.EntityManagerFactory;
 | 
			
		||||
 | 
			
		||||
import org.junit.jupiter.api.Test;
 | 
			
		||||
 | 
			
		||||
import org.springframework.boot.autoconfigure.AutoConfigurations;
 | 
			
		||||
import org.springframework.boot.autoconfigure.TestAutoConfigurationPackage;
 | 
			
		||||
import org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoConfiguration;
 | 
			
		||||
import org.springframework.boot.autoconfigure.data.alt.elasticsearch.CityElasticsearchDbRepository;
 | 
			
		||||
import org.springframework.boot.autoconfigure.data.alt.jpa.CityJpaRepository;
 | 
			
		||||
import org.springframework.boot.autoconfigure.data.alt.mongo.CityMongoDbRepository;
 | 
			
		||||
import org.springframework.boot.autoconfigure.data.jpa.city.City;
 | 
			
		||||
import org.springframework.boot.autoconfigure.data.jpa.city.CityRepository;
 | 
			
		||||
import org.springframework.boot.autoconfigure.jdbc.EmbeddedDataSourceConfiguration;
 | 
			
		||||
import org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration;
 | 
			
		||||
import org.springframework.boot.autoconfigure.task.TaskExecutionAutoConfiguration;
 | 
			
		||||
import org.springframework.boot.autoconfigure.task.TaskSchedulingAutoConfiguration;
 | 
			
		||||
import org.springframework.boot.test.context.runner.ApplicationContextRunner;
 | 
			
		||||
import org.springframework.context.annotation.Bean;
 | 
			
		||||
import org.springframework.context.annotation.ComponentScan.Filter;
 | 
			
		||||
import org.springframework.context.annotation.Configuration;
 | 
			
		||||
import org.springframework.context.annotation.FilterType;
 | 
			
		||||
import org.springframework.context.annotation.Import;
 | 
			
		||||
import org.springframework.core.task.SimpleAsyncTaskExecutor;
 | 
			
		||||
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
 | 
			
		||||
import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
 | 
			
		||||
import org.springframework.scheduling.annotation.EnableScheduling;
 | 
			
		||||
import org.springframework.transaction.PlatformTransactionManager;
 | 
			
		||||
import org.springframework.beans.factory.BeanCreationException;
 | 
			
		||||
import org.springframework.boot.testsupport.classpath.ClassPathExclusions;
 | 
			
		||||
 | 
			
		||||
import static org.assertj.core.api.Assertions.assertThat;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Tests for {@link JpaRepositoriesAutoConfiguration}.
 | 
			
		||||
 * Tests for {@link JpaRepositoriesAutoConfiguration} without Spring Data Envers on the
 | 
			
		||||
 * classpath.
 | 
			
		||||
 *
 | 
			
		||||
 * @author Dave Syer
 | 
			
		||||
 * @author Oliver Gierke
 | 
			
		||||
 * @author Scott Frederick
 | 
			
		||||
 * @author Stefano Cordio
 | 
			
		||||
 */
 | 
			
		||||
class JpaRepositoriesAutoConfigurationTests {
 | 
			
		||||
 | 
			
		||||
	private final ApplicationContextRunner contextRunner = new ApplicationContextRunner()
 | 
			
		||||
			.withConfiguration(AutoConfigurations.of(HibernateJpaAutoConfiguration.class,
 | 
			
		||||
					JpaRepositoriesAutoConfiguration.class, PropertyPlaceholderAutoConfiguration.class))
 | 
			
		||||
			.withUserConfiguration(EmbeddedDataSourceConfiguration.class);
 | 
			
		||||
@ClassPathExclusions("spring-data-envers-*.jar")
 | 
			
		||||
class JpaRepositoriesAutoConfigurationTests extends AbstractJpaRepositoriesAutoConfigurationTests {
 | 
			
		||||
 | 
			
		||||
	@Test
 | 
			
		||||
	void testDefaultRepositoryConfiguration() {
 | 
			
		||||
		this.contextRunner.withUserConfiguration(TestConfiguration.class).run((context) -> {
 | 
			
		||||
			assertThat(context).hasSingleBean(CityRepository.class);
 | 
			
		||||
			assertThat(context).hasSingleBean(PlatformTransactionManager.class);
 | 
			
		||||
			assertThat(context).hasSingleBean(EntityManagerFactory.class);
 | 
			
		||||
			assertThat(context.getBean(LocalContainerEntityManagerFactoryBean.class).getBootstrapExecutor()).isNull();
 | 
			
		||||
		});
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	@Test
 | 
			
		||||
	void testOverrideRepositoryConfiguration() {
 | 
			
		||||
		this.contextRunner.withUserConfiguration(CustomConfiguration.class).run((context) -> {
 | 
			
		||||
			assertThat(context).hasSingleBean(CityJpaRepository.class);
 | 
			
		||||
			assertThat(context).hasSingleBean(PlatformTransactionManager.class);
 | 
			
		||||
			assertThat(context).hasSingleBean(EntityManagerFactory.class);
 | 
			
		||||
		});
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	@Test
 | 
			
		||||
	void autoConfigurationShouldNotKickInEvenIfManualConfigDidNotCreateAnyRepositories() {
 | 
			
		||||
		this.contextRunner.withUserConfiguration(SortOfInvalidCustomConfiguration.class)
 | 
			
		||||
				.run((context) -> assertThat(context).doesNotHaveBean(CityRepository.class));
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	@Test
 | 
			
		||||
	void whenBootstrapModeIsLazyWithMultipleAsyncExecutorBootstrapExecutorIsConfigured() {
 | 
			
		||||
		this.contextRunner.withUserConfiguration(MultipleAsyncTaskExecutorConfiguration.class)
 | 
			
		||||
				.withConfiguration(AutoConfigurations.of(TaskExecutionAutoConfiguration.class,
 | 
			
		||||
						TaskSchedulingAutoConfiguration.class))
 | 
			
		||||
				.withPropertyValues("spring.data.jpa.repositories.bootstrap-mode=lazy")
 | 
			
		||||
				.run((context) -> assertThat(
 | 
			
		||||
						context.getBean(LocalContainerEntityManagerFactoryBean.class).getBootstrapExecutor())
 | 
			
		||||
								.isEqualTo(context.getBean("applicationTaskExecutor")));
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	@Test
 | 
			
		||||
	void whenBootstrapModeIsLazyWithSingleAsyncExecutorBootstrapExecutorIsConfigured() {
 | 
			
		||||
		this.contextRunner.withUserConfiguration(SingleAsyncTaskExecutorConfiguration.class)
 | 
			
		||||
				.withPropertyValues("spring.data.jpa.repositories.bootstrap-mode=lazy")
 | 
			
		||||
				.run((context) -> assertThat(
 | 
			
		||||
						context.getBean(LocalContainerEntityManagerFactoryBean.class).getBootstrapExecutor())
 | 
			
		||||
								.isEqualTo(context.getBean("testAsyncTaskExecutor")));
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	@Test
 | 
			
		||||
	void whenBootstrapModeIsDeferredBootstrapExecutorIsConfigured() {
 | 
			
		||||
		this.contextRunner.withUserConfiguration(MultipleAsyncTaskExecutorConfiguration.class)
 | 
			
		||||
				.withConfiguration(AutoConfigurations.of(TaskExecutionAutoConfiguration.class,
 | 
			
		||||
						TaskSchedulingAutoConfiguration.class))
 | 
			
		||||
				.withPropertyValues("spring.data.jpa.repositories.bootstrap-mode=deferred")
 | 
			
		||||
				.run((context) -> assertThat(
 | 
			
		||||
						context.getBean(LocalContainerEntityManagerFactoryBean.class).getBootstrapExecutor())
 | 
			
		||||
								.isEqualTo(context.getBean("applicationTaskExecutor")));
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	@Test
 | 
			
		||||
	void whenBootstrapModeIsDefaultBootstrapExecutorIsNotConfigured() {
 | 
			
		||||
		this.contextRunner.withUserConfiguration(MultipleAsyncTaskExecutorConfiguration.class)
 | 
			
		||||
				.withConfiguration(AutoConfigurations.of(TaskExecutionAutoConfiguration.class,
 | 
			
		||||
						TaskSchedulingAutoConfiguration.class))
 | 
			
		||||
				.withPropertyValues("spring.data.jpa.repositories.bootstrap-mode=default").run((context) -> assertThat(
 | 
			
		||||
						context.getBean(LocalContainerEntityManagerFactoryBean.class).getBootstrapExecutor()).isNull());
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	@Test
 | 
			
		||||
	void bootstrapModeIsDefaultByDefault() {
 | 
			
		||||
		this.contextRunner.withUserConfiguration(MultipleAsyncTaskExecutorConfiguration.class)
 | 
			
		||||
				.withConfiguration(AutoConfigurations.of(TaskExecutionAutoConfiguration.class,
 | 
			
		||||
						TaskSchedulingAutoConfiguration.class))
 | 
			
		||||
				.run((context) -> assertThat(
 | 
			
		||||
						context.getBean(LocalContainerEntityManagerFactoryBean.class).getBootstrapExecutor()).isNull());
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	@Configuration(proxyBeanMethods = false)
 | 
			
		||||
	@EnableScheduling
 | 
			
		||||
	@Import(TestConfiguration.class)
 | 
			
		||||
	static class MultipleAsyncTaskExecutorConfiguration {
 | 
			
		||||
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	@Configuration(proxyBeanMethods = false)
 | 
			
		||||
	@Import(TestConfiguration.class)
 | 
			
		||||
	static class SingleAsyncTaskExecutorConfiguration {
 | 
			
		||||
 | 
			
		||||
		@Bean
 | 
			
		||||
		SimpleAsyncTaskExecutor testAsyncTaskExecutor() {
 | 
			
		||||
			return new SimpleAsyncTaskExecutor();
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	@Configuration(proxyBeanMethods = false)
 | 
			
		||||
	@TestAutoConfigurationPackage(City.class)
 | 
			
		||||
	static class TestConfiguration {
 | 
			
		||||
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	@Configuration(proxyBeanMethods = false)
 | 
			
		||||
	@EnableJpaRepositories(
 | 
			
		||||
			basePackageClasses = org.springframework.boot.autoconfigure.data.alt.jpa.CityJpaRepository.class,
 | 
			
		||||
			excludeFilters = { @Filter(type = FilterType.ASSIGNABLE_TYPE, value = CityMongoDbRepository.class),
 | 
			
		||||
					@Filter(type = FilterType.ASSIGNABLE_TYPE, value = CityElasticsearchDbRepository.class) })
 | 
			
		||||
	@TestAutoConfigurationPackage(City.class)
 | 
			
		||||
	static class CustomConfiguration {
 | 
			
		||||
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	@Configuration(proxyBeanMethods = false)
 | 
			
		||||
	// To not find any repositories
 | 
			
		||||
	@EnableJpaRepositories("foo.bar")
 | 
			
		||||
	@TestAutoConfigurationPackage(City.class)
 | 
			
		||||
	static class SortOfInvalidCustomConfiguration {
 | 
			
		||||
 | 
			
		||||
	void autoConfigurationShouldFailWithRevisionRepository() {
 | 
			
		||||
		this.contextRunner.withUserConfiguration(RevisionRepositoryConfiguration.class)
 | 
			
		||||
				.run((context) -> assertThat(context).getFailure().isInstanceOf(BeanCreationException.class));
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -0,0 +1,57 @@
 | 
			
		|||
/*
 | 
			
		||||
 * Copyright 2012-2021 the original author or authors.
 | 
			
		||||
 *
 | 
			
		||||
 * Licensed under the Apache License, Version 2.0 (the "License");
 | 
			
		||||
 * you may not use this file except in compliance with the License.
 | 
			
		||||
 * You may obtain a copy of the License at
 | 
			
		||||
 *
 | 
			
		||||
 *      https://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
 *
 | 
			
		||||
 * Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
 * distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
 * See the License for the specific language governing permissions and
 | 
			
		||||
 * limitations under the License.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
package org.springframework.boot.autoconfigure.data.jpa.country;
 | 
			
		||||
 | 
			
		||||
import java.io.Serializable;
 | 
			
		||||
 | 
			
		||||
import javax.persistence.Column;
 | 
			
		||||
import javax.persistence.Entity;
 | 
			
		||||
import javax.persistence.GeneratedValue;
 | 
			
		||||
import javax.persistence.Id;
 | 
			
		||||
 | 
			
		||||
import org.hibernate.envers.Audited;
 | 
			
		||||
 | 
			
		||||
@Entity
 | 
			
		||||
public class Country implements Serializable {
 | 
			
		||||
 | 
			
		||||
	private static final long serialVersionUID = 1L;
 | 
			
		||||
 | 
			
		||||
	@Id
 | 
			
		||||
	@GeneratedValue
 | 
			
		||||
	private Long id;
 | 
			
		||||
 | 
			
		||||
	@Audited
 | 
			
		||||
	@Column
 | 
			
		||||
	private String name;
 | 
			
		||||
 | 
			
		||||
	public Long getId() {
 | 
			
		||||
		return this.id;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	public void setId(Long id) {
 | 
			
		||||
		this.id = id;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	public String getName() {
 | 
			
		||||
		return this.name;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	public void setName(String name) {
 | 
			
		||||
		this.name = name;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,24 @@
 | 
			
		|||
/*
 | 
			
		||||
 * Copyright 2012-2021 the original author or authors.
 | 
			
		||||
 *
 | 
			
		||||
 * Licensed under the Apache License, Version 2.0 (the "License");
 | 
			
		||||
 * you may not use this file except in compliance with the License.
 | 
			
		||||
 * You may obtain a copy of the License at
 | 
			
		||||
 *
 | 
			
		||||
 *      https://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
 *
 | 
			
		||||
 * Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
 * distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
 * See the License for the specific language governing permissions and
 | 
			
		||||
 * limitations under the License.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
package org.springframework.boot.autoconfigure.data.jpa.country;
 | 
			
		||||
 | 
			
		||||
import org.springframework.data.jpa.repository.JpaRepository;
 | 
			
		||||
import org.springframework.data.repository.history.RevisionRepository;
 | 
			
		||||
 | 
			
		||||
public interface CountryRepository extends JpaRepository<Country, Long>, RevisionRepository<Country, Long, Integer> {
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -100,6 +100,7 @@ dependencies {
 | 
			
		|||
	implementation("org.springframework.data:spring-data-cassandra")
 | 
			
		||||
	implementation("org.springframework.data:spring-data-couchbase")
 | 
			
		||||
	implementation("org.springframework.data:spring-data-elasticsearch")
 | 
			
		||||
	implementation("org.springframework.data:spring-data-envers")
 | 
			
		||||
	implementation("org.springframework.data:spring-data-jpa")
 | 
			
		||||
	implementation("org.springframework.data:spring-data-ldap")
 | 
			
		||||
	implementation("org.springframework.data:spring-data-mongodb")
 | 
			
		||||
| 
						 | 
				
			
			@ -226,6 +227,7 @@ tasks.withType(org.asciidoctor.gradle.jvm.AbstractAsciidoctorTask) {
 | 
			
		|||
					"spring-boot-version": project.version,
 | 
			
		||||
					"spring-data-commons-version": versionConstraints["org.springframework.data:spring-data-commons"],
 | 
			
		||||
					"spring-data-couchbase-version": versionConstraints["org.springframework.data:spring-data-couchbase"],
 | 
			
		||||
					"spring-data-envers-version": versionConstraints["org.springframework.data:spring-data-envers"],
 | 
			
		||||
					"spring-data-jdbc-version": versionConstraints["org.springframework.data:spring-data-jdbc"],
 | 
			
		||||
					"spring-data-jpa-version": versionConstraints["org.springframework.data:spring-data-jpa"],
 | 
			
		||||
					"spring-data-mongodb-version": versionConstraints["org.springframework.data:spring-data-mongodb"],
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -60,6 +60,8 @@
 | 
			
		|||
:spring-data-couchbase-docs: https://docs.spring.io/spring-data/couchbase/docs/{spring-data-couchbase-version}/reference/html/
 | 
			
		||||
:spring-data-elasticsearch: https://spring.io/projects/spring-data-elasticsearch
 | 
			
		||||
:spring-data-elasticsearch-docs: https://docs.spring.io/spring-data/elasticsearch/docs/current/reference/html/
 | 
			
		||||
:spring-data-envers: https://spring.io/projects/spring-data-envers
 | 
			
		||||
:spring-data-envers-doc: https://docs.spring.io/spring-data/envers/docs/{spring-data-envers-version}/reference/html/
 | 
			
		||||
:spring-data-gemfire: https://spring.io/projects/spring-data-gemfire
 | 
			
		||||
:spring-data-geode: https://spring.io/projects/spring-data-geode
 | 
			
		||||
:spring-data-jpa: https://spring.io/projects/spring-data-jpa
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -247,6 +247,21 @@ For complete details, see the {spring-data-jpa-docs}[Spring Data JPA reference d
 | 
			
		|||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
[[features.sql.jpa-and-spring-data.envers-repositories]]
 | 
			
		||||
==== Spring Data Envers Repositories
 | 
			
		||||
If {spring-data-envers}[Spring Data Envers] is available, JPA repositories are auto-configured to support typical Envers queries.
 | 
			
		||||
 | 
			
		||||
To use Spring Data Envers, make sure your repository extends from `RevisionRepository` as show in the following example:
 | 
			
		||||
 | 
			
		||||
[source,java,indent=0,subs="verbatim"]
 | 
			
		||||
----
 | 
			
		||||
include::{docs-java}/features/sql/jpaandspringdata/repositories/CountryRepository.java[]
 | 
			
		||||
----
 | 
			
		||||
 | 
			
		||||
NOTE: For more details, check the {spring-data-envers-doc}[Spring Data Envers reference documentation].
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
[[features.sql.jpa-and-spring-data.creating-and-dropping]]
 | 
			
		||||
==== Creating and Dropping JPA Databases
 | 
			
		||||
By default, JPA databases are automatically created *only* if you use an embedded database (H2, HSQL, or Derby).
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -0,0 +1,55 @@
 | 
			
		|||
/*
 | 
			
		||||
 * Copyright 2012-2021 the original author or authors.
 | 
			
		||||
 *
 | 
			
		||||
 * Licensed under the Apache License, Version 2.0 (the "License");
 | 
			
		||||
 * you may not use this file except in compliance with the License.
 | 
			
		||||
 * You may obtain a copy of the License at
 | 
			
		||||
 *
 | 
			
		||||
 *      https://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
 *
 | 
			
		||||
 * Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
 * distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
 * See the License for the specific language governing permissions and
 | 
			
		||||
 * limitations under the License.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
package org.springframework.boot.docs.features.sql.jpaandspringdata.entityclasses;
 | 
			
		||||
 | 
			
		||||
import java.io.Serializable;
 | 
			
		||||
 | 
			
		||||
import javax.persistence.Column;
 | 
			
		||||
import javax.persistence.Entity;
 | 
			
		||||
import javax.persistence.GeneratedValue;
 | 
			
		||||
import javax.persistence.Id;
 | 
			
		||||
 | 
			
		||||
import org.hibernate.envers.Audited;
 | 
			
		||||
 | 
			
		||||
@Entity
 | 
			
		||||
public class Country implements Serializable {
 | 
			
		||||
 | 
			
		||||
	@Id
 | 
			
		||||
	@GeneratedValue
 | 
			
		||||
	private Long id;
 | 
			
		||||
 | 
			
		||||
	@Audited
 | 
			
		||||
	@Column(nullable = false)
 | 
			
		||||
	private String name;
 | 
			
		||||
 | 
			
		||||
	public Long getId() {
 | 
			
		||||
		return this.id;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	public void setId(Long id) {
 | 
			
		||||
		this.id = id;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	public String getName() {
 | 
			
		||||
		return this.name;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	public void setName(String name) {
 | 
			
		||||
		this.name = name;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,29 @@
 | 
			
		|||
/*
 | 
			
		||||
 * Copyright 2012-2021 the original author or authors.
 | 
			
		||||
 *
 | 
			
		||||
 * Licensed under the Apache License, Version 2.0 (the "License");
 | 
			
		||||
 * you may not use this file except in compliance with the License.
 | 
			
		||||
 * You may obtain a copy of the License at
 | 
			
		||||
 *
 | 
			
		||||
 *      https://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
 *
 | 
			
		||||
 * Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
 * distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
 * See the License for the specific language governing permissions and
 | 
			
		||||
 * limitations under the License.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
package org.springframework.boot.docs.features.sql.jpaandspringdata.repositories;
 | 
			
		||||
 | 
			
		||||
import org.springframework.boot.docs.features.sql.jpaandspringdata.entityclasses.Country;
 | 
			
		||||
import org.springframework.data.domain.Page;
 | 
			
		||||
import org.springframework.data.domain.Pageable;
 | 
			
		||||
import org.springframework.data.repository.Repository;
 | 
			
		||||
import org.springframework.data.repository.history.RevisionRepository;
 | 
			
		||||
 | 
			
		||||
public interface CountryRepository extends RevisionRepository<Country, Long, Integer>, Repository<Country, Long> {
 | 
			
		||||
 | 
			
		||||
	Page<Country> findAll(Pageable pageable);
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
		Loading…
	
		Reference in New Issue