Add @DataJpaTest annotation
Add @DataJpaTest and @AutoConfigureTestDatabase annotations to allow testing of an application "slice" that only deals JPA. See gh-4901
This commit is contained in:
parent
bbc91cc03f
commit
81d5635571
|
@ -34,6 +34,11 @@
|
|||
<artifactId>javax.servlet-api</artifactId>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>javax.transaction</groupId>
|
||||
<artifactId>javax.transaction-api</artifactId>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.fasterxml.jackson.core</groupId>
|
||||
<artifactId>jackson-databind</artifactId>
|
||||
|
@ -45,12 +50,28 @@
|
|||
<version>2.19</version>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.hibernate</groupId>
|
||||
<artifactId>hibernate-entitymanager</artifactId>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<groupId>org.jboss.spec.javax.transaction</groupId>
|
||||
<artifactId>jboss-transaction-api_1.2_spec</artifactId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.seleniumhq.selenium</groupId>
|
||||
<artifactId>selenium-htmlunit-driver</artifactId>
|
||||
<version>2.52.0</version>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-orm</artifactId>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-test</artifactId>
|
||||
|
@ -66,6 +87,17 @@
|
|||
<artifactId>spring-webmvc</artifactId>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.data</groupId>
|
||||
<artifactId>spring-data-jpa</artifactId>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<groupId>org.aspectj</groupId>
|
||||
<artifactId>aspectjrt</artifactId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
<!-- Test -->
|
||||
<dependency>
|
||||
<groupId>org.aspectj</groupId>
|
||||
|
@ -77,6 +109,16 @@
|
|||
<artifactId>aspectjweaver</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.h2database</groupId>
|
||||
<artifactId>h2</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.hsqldb</groupId>
|
||||
<artifactId>hsqldb</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.skyscreamer</groupId>
|
||||
<artifactId>jsonassert</artifactId>
|
||||
|
|
|
@ -0,0 +1,78 @@
|
|||
/*
|
||||
* Copyright 2012-2016 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
|
||||
*
|
||||
* http://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.test.autoconfigure.orm.jpa;
|
||||
|
||||
import java.lang.annotation.Documented;
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
import javax.sql.DataSource;
|
||||
|
||||
import org.springframework.boot.autoconfigure.ImportAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.jdbc.EmbeddedDatabaseConnection;
|
||||
import org.springframework.boot.test.autoconfigure.properties.PropertyMapping;
|
||||
|
||||
/**
|
||||
* Annotation that can be applied to a test class to configure a test database to use
|
||||
* instead of any application defined or auto-configured {@link DataSource}.
|
||||
*
|
||||
* @author Phillip Webb
|
||||
* @see TestDatabaseAutoConfiguration
|
||||
*/
|
||||
@Documented
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Target({ ElementType.TYPE, ElementType.METHOD })
|
||||
@ImportAutoConfiguration(TestDatabaseAutoConfiguration.class)
|
||||
@PropertyMapping("spring.test.database")
|
||||
public @interface AutoConfigureTestDatabase {
|
||||
|
||||
/**
|
||||
* If the test database should replace any existing.
|
||||
*/
|
||||
Replace replace() default Replace.ANY;
|
||||
|
||||
/**
|
||||
* The type of connection to be establish when {@link #replace() replacing} the data
|
||||
* source. By default will attempt to detect the connection based on the classpath.
|
||||
*/
|
||||
EmbeddedDatabaseConnection connection() default EmbeddedDatabaseConnection.NONE;
|
||||
|
||||
/**
|
||||
* What the test database can replace.
|
||||
*/
|
||||
enum Replace {
|
||||
|
||||
/**
|
||||
* Replace any DataSource bean (auto-configured or manually defined).
|
||||
*/
|
||||
ANY,
|
||||
|
||||
/**
|
||||
* Only replace auto-configured DataSource.
|
||||
*/
|
||||
AUTO_CONFIGURED,
|
||||
|
||||
/**
|
||||
* Don't replace the application default DataSource.
|
||||
*/
|
||||
NONE
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,40 @@
|
|||
/*
|
||||
* Copyright 2012-2016 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
|
||||
*
|
||||
* http://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.test.autoconfigure.orm.jpa;
|
||||
|
||||
import java.lang.annotation.Documented;
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
import org.springframework.boot.autoconfigure.ImportAutoConfiguration;
|
||||
|
||||
/**
|
||||
* Annotation that can be applied to a test class to enable and configure
|
||||
* auto-configuration of a {@link TestEntityManager}.
|
||||
*
|
||||
* @author Phillip Webb
|
||||
* @see TestEntityManagerAutoConfiguration
|
||||
*/
|
||||
@Documented
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Target({ ElementType.TYPE, ElementType.METHOD })
|
||||
@ImportAutoConfiguration(TestEntityManagerAutoConfiguration.class)
|
||||
public @interface AutoConfigureTestEntityManager {
|
||||
|
||||
}
|
|
@ -0,0 +1,97 @@
|
|||
/*
|
||||
* Copyright 2012-2016 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
|
||||
*
|
||||
* http://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.test.autoconfigure.orm.jpa;
|
||||
|
||||
import java.lang.annotation.Documented;
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Inherited;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
import org.springframework.boot.test.autoconfigure.OverrideAutoConfiguration;
|
||||
import org.springframework.boot.test.autoconfigure.filter.TypeExcludeFilters;
|
||||
import org.springframework.boot.test.autoconfigure.properties.PropertyMapping;
|
||||
import org.springframework.boot.test.context.SpringApplicationTest;
|
||||
import org.springframework.boot.test.context.SpringBootTestContextBootstrapper;
|
||||
import org.springframework.context.annotation.ComponentScan.Filter;
|
||||
import org.springframework.test.context.BootstrapWith;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
/**
|
||||
* Annotation that can be used in combination with {@code @RunWith(SpringRunner.class)}
|
||||
* for a typical JPA test. Can be used when a test focuses <strong>only</strong> on JPA
|
||||
* components.
|
||||
* <p>
|
||||
* Using this annotation will disable full auto-configuration and instead apply only
|
||||
* configuration relevant to JPA tests.
|
||||
* <p>
|
||||
* By default, tests annotated with {@code @DataJpaTest} will use an embedded in-memory
|
||||
* database (replacing any explicit or usually auto-configured DataSource). The
|
||||
* {@link AutoConfigureTestDatabase @AutoConfigureTestDatabase} annotation can be used to
|
||||
* override these settings.
|
||||
* <p>
|
||||
* If you are looking to load your full application configuration, but use an embedded
|
||||
* database, you should consider {@link SpringApplicationTest @SpringApplicationTest}
|
||||
* combined with {@link AutoConfigureTestDatabase @AutoConfigureTestDatabase} rather than
|
||||
* this annotation.
|
||||
*
|
||||
* @author Phillip Webb
|
||||
* @see AutoConfigureTestDatabase
|
||||
*/
|
||||
@Target(ElementType.TYPE)
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Documented
|
||||
@Inherited
|
||||
@BootstrapWith(SpringBootTestContextBootstrapper.class)
|
||||
@OverrideAutoConfiguration(enabled = false)
|
||||
@TypeExcludeFilters(DataJpaTypeExcludeFilter.class)
|
||||
@Transactional
|
||||
@ImportDataJpaAutoConfiguration
|
||||
@AutoConfigureTestDatabase
|
||||
@AutoConfigureTestEntityManager
|
||||
public @interface DataJpaTest {
|
||||
|
||||
/**
|
||||
* If SQL output should be logged.
|
||||
*/
|
||||
@PropertyMapping("spring.jpa.show-sql")
|
||||
boolean showSql() default true;
|
||||
|
||||
/**
|
||||
* Determines if default filtering should be used with
|
||||
* {@link SpringBootApplication @SpringBootApplication}. By default no beans are
|
||||
* included.
|
||||
* @see #includeFilters()
|
||||
* @see #excludeFilters()
|
||||
*/
|
||||
boolean useDefaultFilters() default true;
|
||||
|
||||
/**
|
||||
* A set of include filters which can be used to add otherwise filtered beans to the
|
||||
* application context.
|
||||
*/
|
||||
Filter[] includeFilters() default {};
|
||||
|
||||
/**
|
||||
* A set of exclude filters which can be used to filter beans that would otherwise be
|
||||
* added to the application context.
|
||||
*/
|
||||
Filter[] excludeFilters() default {};
|
||||
|
||||
}
|
|
@ -0,0 +1,76 @@
|
|||
/*
|
||||
* Copyright 2012-2016 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
|
||||
*
|
||||
* http://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.test.autoconfigure.orm.jpa;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Collections;
|
||||
import java.util.Set;
|
||||
|
||||
import org.springframework.boot.context.TypeExcludeFilter;
|
||||
import org.springframework.boot.test.autoconfigure.filter.AnnotationCustomizableTypeExcludeFilter;
|
||||
import org.springframework.context.annotation.ComponentScan.Filter;
|
||||
import org.springframework.core.annotation.AnnotatedElementUtils;
|
||||
import org.springframework.core.type.classreading.MetadataReader;
|
||||
import org.springframework.core.type.classreading.MetadataReaderFactory;
|
||||
|
||||
/**
|
||||
* {@link TypeExcludeFilter} for {@link DataJpaTest @DataJpaTest}.
|
||||
*
|
||||
* @author Phillip Webb
|
||||
*/
|
||||
class DataJpaTypeExcludeFilter extends AnnotationCustomizableTypeExcludeFilter {
|
||||
|
||||
private final DataJpaTest annotation;
|
||||
|
||||
DataJpaTypeExcludeFilter(Class<?> testClass) {
|
||||
this.annotation = AnnotatedElementUtils.getMergedAnnotation(testClass,
|
||||
DataJpaTest.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean hasAnnotation() {
|
||||
return this.annotation != null;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Filter[] getFilters(FilterType type) {
|
||||
switch (type) {
|
||||
case INCLUDE:
|
||||
return this.annotation.includeFilters();
|
||||
case EXCLUDE:
|
||||
return this.annotation.excludeFilters();
|
||||
}
|
||||
throw new IllegalStateException("Unsupported type " + type);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean isUseDefaultFilters() {
|
||||
return this.annotation.useDefaultFilters();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean defaultInclude(MetadataReader metadataReader,
|
||||
MetadataReaderFactory metadataReaderFactory) throws IOException {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Set<Class<?>> getDefaultIncudes() {
|
||||
return Collections.emptySet();
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,50 @@
|
|||
/*
|
||||
* Copyright 2012-2016 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
|
||||
*
|
||||
* http://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.test.autoconfigure.orm.jpa;
|
||||
|
||||
import java.lang.annotation.Documented;
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
import org.springframework.boot.autoconfigure.ImportAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.data.jpa.JpaRepositoriesAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.jdbc.DataSourceTransactionManagerAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.transaction.TransactionAutoConfiguration;
|
||||
|
||||
/**
|
||||
* {@link ImportAutoConfiguration Auto-configuration imports} for typical Data JPA tests.
|
||||
* Most tests should consider using {@link DataJpaTest @DataJpaTest} rather than using
|
||||
* this annotation directly.
|
||||
*
|
||||
* @author Phillip Webb
|
||||
* @since 1.4.0
|
||||
* @see DataJpaTest
|
||||
*/
|
||||
@Target(ElementType.TYPE)
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Documented
|
||||
@ImportAutoConfiguration({ HibernateJpaAutoConfiguration.class,
|
||||
JpaRepositoriesAutoConfiguration.class, TransactionAutoConfiguration.class,
|
||||
DataSourceTransactionManagerAutoConfiguration.class,
|
||||
DataSourceAutoConfiguration.class })
|
||||
public @interface ImportDataJpaAutoConfiguration {
|
||||
|
||||
}
|
|
@ -0,0 +1,192 @@
|
|||
/*
|
||||
* Copyright 2012-2016 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
|
||||
*
|
||||
* http://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.test.autoconfigure.orm.jpa;
|
||||
|
||||
import javax.sql.DataSource;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
import org.springframework.beans.BeansException;
|
||||
import org.springframework.beans.factory.FactoryBean;
|
||||
import org.springframework.beans.factory.InitializingBean;
|
||||
import org.springframework.beans.factory.config.BeanDefinition;
|
||||
import org.springframework.beans.factory.config.BeanDefinitionHolder;
|
||||
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
|
||||
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
|
||||
import org.springframework.beans.factory.support.BeanDefinitionRegistryPostProcessor;
|
||||
import org.springframework.beans.factory.support.RootBeanDefinition;
|
||||
import org.springframework.boot.autoconfigure.AutoConfigureBefore;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
|
||||
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.jdbc.EmbeddedDatabaseConnection;
|
||||
import org.springframework.context.EnvironmentAware;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.core.Ordered;
|
||||
import org.springframework.core.annotation.Order;
|
||||
import org.springframework.core.env.Environment;
|
||||
import org.springframework.jdbc.datasource.embedded.EmbeddedDatabase;
|
||||
import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseBuilder;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.ObjectUtils;
|
||||
|
||||
/**
|
||||
* Auto-configuration for a test database.
|
||||
*
|
||||
* @author Phillip Webb
|
||||
* @see AutoConfigureTestDatabase
|
||||
*/
|
||||
@Configuration
|
||||
@AutoConfigureBefore(DataSourceAutoConfiguration.class)
|
||||
class TestDatabaseAutoConfiguration {
|
||||
|
||||
private final Environment environment;
|
||||
|
||||
TestDatabaseAutoConfiguration(Environment environment) {
|
||||
this.environment = environment;
|
||||
}
|
||||
|
||||
@Bean
|
||||
@ConditionalOnProperty(prefix = "spring.test.database", name = "replace", havingValue = "AUTO_CONFIGURED")
|
||||
@ConditionalOnMissingBean
|
||||
public DataSource dataSource() {
|
||||
return new EmbeddedDataSourceFactory(this.environment).getEmbeddedDatabase();
|
||||
}
|
||||
|
||||
@Bean
|
||||
@ConditionalOnProperty(prefix = "spring.test.database", name = "replace", havingValue = "ANY", matchIfMissing = true)
|
||||
public static EmbeddedDataSourceBeanFactoryPostProcessor embeddedDataSourceBeanFactoryPostProcessor() {
|
||||
return new EmbeddedDataSourceBeanFactoryPostProcessor();
|
||||
}
|
||||
|
||||
@Order(Ordered.LOWEST_PRECEDENCE)
|
||||
private static class EmbeddedDataSourceBeanFactoryPostProcessor
|
||||
implements BeanDefinitionRegistryPostProcessor {
|
||||
|
||||
private static final Log logger = LogFactory
|
||||
.getLog(EmbeddedDataSourceBeanFactoryPostProcessor.class);
|
||||
|
||||
@Override
|
||||
public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry)
|
||||
throws BeansException {
|
||||
Assert.isInstanceOf(ConfigurableListableBeanFactory.class, registry,
|
||||
"Test Database Auto-configuration can only be "
|
||||
+ "used with a ConfigurableListableBeanFactory");
|
||||
process(registry, (ConfigurableListableBeanFactory) registry);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory)
|
||||
throws BeansException {
|
||||
}
|
||||
|
||||
private void process(BeanDefinitionRegistry registry,
|
||||
ConfigurableListableBeanFactory beanFactory) {
|
||||
BeanDefinitionHolder holder = getDataSourceBeanDefinition(beanFactory);
|
||||
logger.info("Replacing '" + holder.getBeanName()
|
||||
+ "' DataSource bean with embedded version");
|
||||
registry.registerBeanDefinition(holder.getBeanName(),
|
||||
createEmbeddedBeanDefinition());
|
||||
}
|
||||
|
||||
private BeanDefinition createEmbeddedBeanDefinition() {
|
||||
return new RootBeanDefinition(EmbeddedDataSourceFactoryBean.class);
|
||||
}
|
||||
|
||||
private BeanDefinitionHolder getDataSourceBeanDefinition(
|
||||
ConfigurableListableBeanFactory beanFactory) {
|
||||
String[] beanNames = beanFactory.getBeanNamesForType(DataSource.class);
|
||||
if (!ObjectUtils.isEmpty(beanNames)) {
|
||||
if (beanNames.length == 1) {
|
||||
String beanName = beanNames[0];
|
||||
BeanDefinition beanDefinition = beanFactory
|
||||
.getBeanDefinition(beanName);
|
||||
return new BeanDefinitionHolder(beanDefinition, beanName);
|
||||
}
|
||||
for (String beanName : beanNames) {
|
||||
BeanDefinition beanDefinition = beanFactory
|
||||
.getBeanDefinition(beanName);
|
||||
if (beanDefinition.isPrimary()) {
|
||||
return new BeanDefinitionHolder(beanDefinition, beanName);
|
||||
}
|
||||
logger.warn("No primary DataSource found, "
|
||||
+ "embedded version will not be used");
|
||||
}
|
||||
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private static class EmbeddedDataSourceFactoryBean
|
||||
implements FactoryBean<DataSource>, EnvironmentAware, InitializingBean {
|
||||
|
||||
private EmbeddedDataSourceFactory factory;
|
||||
|
||||
private EmbeddedDatabase embeddedDatabase;
|
||||
|
||||
@Override
|
||||
public void setEnvironment(Environment environment) {
|
||||
this.factory = new EmbeddedDataSourceFactory(environment);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void afterPropertiesSet() throws Exception {
|
||||
this.embeddedDatabase = this.factory.getEmbeddedDatabase();
|
||||
}
|
||||
|
||||
@Override
|
||||
public DataSource getObject() throws Exception {
|
||||
return this.embeddedDatabase;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<?> getObjectType() {
|
||||
return EmbeddedDatabase.class;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSingleton() {
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private static class EmbeddedDataSourceFactory {
|
||||
|
||||
private final Environment environment;
|
||||
|
||||
EmbeddedDataSourceFactory(Environment environment) {
|
||||
this.environment = environment;
|
||||
}
|
||||
|
||||
public EmbeddedDatabase getEmbeddedDatabase() {
|
||||
EmbeddedDatabaseConnection connection = this.environment.getProperty(
|
||||
"spring.test.database.connection", EmbeddedDatabaseConnection.class,
|
||||
EmbeddedDatabaseConnection.NONE);
|
||||
if (EmbeddedDatabaseConnection.NONE.equals(connection)) {
|
||||
connection = EmbeddedDatabaseConnection.get(getClass().getClassLoader());
|
||||
}
|
||||
return new EmbeddedDatabaseBuilder().setType(connection.getType()).build();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,245 @@
|
|||
/*
|
||||
* Copyright 2012-2016 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
|
||||
*
|
||||
* http://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.test.autoconfigure.orm.jpa;
|
||||
|
||||
import javax.persistence.EntityManager;
|
||||
import javax.persistence.EntityManagerFactory;
|
||||
import javax.persistence.PersistenceUnitUtil;
|
||||
|
||||
import org.springframework.orm.jpa.EntityManagerFactoryUtils;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
* Alternative to {@link EntityManager} for use in JPA tests. Provides a subset of
|
||||
* {@link EntityManager} methods that are useful for tests as well as helper methods for
|
||||
* common testing tasks such as {@link #persistFlushFind(Object) persist/flush/find}.
|
||||
*
|
||||
* @author Phillip Webb
|
||||
* @since 1.4.0
|
||||
*/
|
||||
public class TestEntityManager {
|
||||
|
||||
private final EntityManagerFactory entityManagerFactory;
|
||||
|
||||
/**
|
||||
* Create a new {@link TestEntityManager} instance for the given
|
||||
* {@link EntityManagerFactory}.
|
||||
* @param entityManagerFactory the source entity manager factory
|
||||
*/
|
||||
public TestEntityManager(EntityManagerFactory entityManagerFactory) {
|
||||
Assert.notNull(entityManagerFactory, "EntityManagerFactory must not be null");
|
||||
this.entityManagerFactory = entityManagerFactory;
|
||||
}
|
||||
|
||||
/**
|
||||
* Make an instance managed and persistent then return it's ID. Delegates to
|
||||
* {@link EntityManager#persist(Object)} then {@link #getId(Object)}.
|
||||
* <p>
|
||||
* Helpful when setting up test data in a test: <pre class="code">
|
||||
* Object entityId = this.testEntityManager.persist(new MyEntity("Spring"));
|
||||
* </pre>
|
||||
* @param entity the source entity
|
||||
* @return the ID of the newly persisted entity
|
||||
*/
|
||||
public Object persistAndGetId(Object entity) {
|
||||
persist(entity);
|
||||
return getId(entity);
|
||||
}
|
||||
|
||||
/**
|
||||
* Make an instance managed and persistent then return it's ID. Delegates to
|
||||
* {@link EntityManager#persist(Object)} then {@link #getId(Object, Class)}.
|
||||
* <p>
|
||||
* Helpful when setting up test data in a test: <pre class="code">
|
||||
* Long entityId = this.testEntityManager.persist(new MyEntity("Spring"), Long.class);
|
||||
* </pre>
|
||||
* @param <T> the ID type
|
||||
* @param entity the source entity
|
||||
* @param idType the ID type
|
||||
* @return the ID of the newly persisted entity
|
||||
*/
|
||||
public <T> T persistAndGetId(Object entity, Class<T> idType) {
|
||||
persist(entity);
|
||||
return getId(entity, idType);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Make an instance managed and persistent. Delegates to
|
||||
* {@link EntityManager#persist(Object)} then returns the original source entity.
|
||||
* <p>
|
||||
* Helpful when setting up test data in a test: <pre class="code">
|
||||
* MyEntity entity = this.testEntityManager.persist(new MyEntity("Spring"));
|
||||
* </pre>
|
||||
* @param <E> the entity type
|
||||
* @param entity the entity to persist
|
||||
* @return the persisted entity
|
||||
*/
|
||||
public <E> E persist(E entity) {
|
||||
Assert.state(getId(entity) == null,
|
||||
"Entity " + entity.getClass().getName() + " already has an ID");
|
||||
getEntityManager().persist(entity);
|
||||
return entity;
|
||||
}
|
||||
|
||||
/**
|
||||
* Make an instance managed and persistent, synchronize the persistence context to the
|
||||
* underlying database and finally find the persisted entity by its ID. Delegates to
|
||||
* {@link #persistAndFlush(Object)} then {@link #find(Class, Object)} with the
|
||||
* {@link #getId(Object) entity ID}.
|
||||
* <p>
|
||||
* Helpful when ensuring that entity data is actually written and read from the
|
||||
* underling database correctly.
|
||||
* @param <E> the entity type
|
||||
* @param entity the entity to persist
|
||||
* @return the entity found using the ID of the persisted entity
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public <E> E persistFlushFind(E entity) {
|
||||
EntityManager entityManager = getEntityManager();
|
||||
persistAndFlush(entity);
|
||||
Object id = getId(entity);
|
||||
entityManager.detach(entity);
|
||||
return (E) entityManager.find(entity.getClass(), id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Make an instance managed and persistent then synchronize the persistence context to
|
||||
* the underlying database. Delegates to {@link EntityManager#persist(Object)} then
|
||||
* {@link #flush()} and finally returns the original source entity.
|
||||
* <p>
|
||||
* Helpful when setting up test data in a test: <pre class="code">
|
||||
* MyEntity entity = this.testEntityManager.persistAndFlush(new MyEntity("Spring"));
|
||||
* </pre>
|
||||
* @param <E> the entity type
|
||||
* @param entity the entity to persist
|
||||
* @return the persisted entity
|
||||
*/
|
||||
public <E> E persistAndFlush(E entity) {
|
||||
persist(entity);
|
||||
flush();
|
||||
return entity;
|
||||
}
|
||||
|
||||
/**
|
||||
* Merge the state of the given entity into the current persistence context. Delegates
|
||||
* to {@link EntityManager#merge(Object)}
|
||||
* @param <E> the entity type
|
||||
* @param entity the entity to merge
|
||||
* @return the merged entity
|
||||
*/
|
||||
public <E> E merge(E entity) {
|
||||
return getEntityManager().merge(entity);
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove the entity instance. Delegates to {@link EntityManager#remove(Object)}
|
||||
* @param entity the entity to remove
|
||||
*/
|
||||
public void remove(Object entity) {
|
||||
getEntityManager().remove(entity);
|
||||
}
|
||||
|
||||
/**
|
||||
* Find by primary key. Delegates to {@link EntityManager#find(Class, Object)}.
|
||||
* @param <E> the entity type
|
||||
* @param entityClass the entity class
|
||||
* @param primaryKey the entity primary key
|
||||
* @return the found entity or {@code null} if the entity does not exist
|
||||
* @see #getId(Object)
|
||||
*/
|
||||
public <E> E find(Class<E> entityClass, Object primaryKey) {
|
||||
return getEntityManager().find(entityClass, primaryKey);
|
||||
}
|
||||
|
||||
/**
|
||||
* Synchronize the persistence context to the underlying database. Delegates to
|
||||
* {@link EntityManager#flush()}.
|
||||
*/
|
||||
public void flush() {
|
||||
getEntityManager().flush();
|
||||
}
|
||||
|
||||
/**
|
||||
* Refresh the state of the instance from the database, overwriting changes made to
|
||||
* the entity, if any. Delegates to {@link EntityManager#refresh(Object)}.
|
||||
* @param <E> the entity type
|
||||
* @param entity the entity to refresh
|
||||
* @return the refreshed entity
|
||||
*/
|
||||
public <E> E refresh(E entity) {
|
||||
getEntityManager().refresh(entity);
|
||||
return entity;
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear the persistence context, causing all managed entities to become detached.
|
||||
* Delegates to {@link EntityManager#clear()}
|
||||
*/
|
||||
public void clear() {
|
||||
getEntityManager().clear();
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove the given entity from the persistence context, causing a managed entity to
|
||||
* become detached. Delegates to {@link EntityManager#detach(Object)}.
|
||||
* @param entity the entity to detach.
|
||||
*/
|
||||
public void detach(Object entity) {
|
||||
getEntityManager().detach(entity);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the ID of the given entity. Delegates to
|
||||
* {@link PersistenceUnitUtil#getIdentifier(Object)}.
|
||||
* @param entity the source entity
|
||||
* @return the ID of the entity or {@code null}
|
||||
* @see #getId(Object, Class)
|
||||
*/
|
||||
public Object getId(Object entity) {
|
||||
return this.entityManagerFactory.getPersistenceUnitUtil().getIdentifier(entity);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the ID of the given entity cast to a specific type. Delegates to
|
||||
* {@link PersistenceUnitUtil#getIdentifier(Object)}.
|
||||
* @param <T> the ID type
|
||||
* @param entity the source entity
|
||||
* @param idType the expected ID type
|
||||
* @return the ID of the entity or {@code null}
|
||||
* @see #getId(Object)
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public <T> T getId(Object entity, Class<T> idType) {
|
||||
Object id = getId(entity);
|
||||
Assert.isInstanceOf(idType, id, "ID missmatch");
|
||||
return (T) id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the underlying {@link EntityManager} that's actually used to perform all
|
||||
* operations.
|
||||
* @return the entity manager
|
||||
*/
|
||||
public final EntityManager getEntityManager() {
|
||||
EntityManager manager = EntityManagerFactoryUtils
|
||||
.getTransactionalEntityManager(this.entityManagerFactory);
|
||||
Assert.state(manager != null, "No transactional EnitiyManager found");
|
||||
return manager;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,46 @@
|
|||
/*
|
||||
* Copyright 2012-2016 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
|
||||
*
|
||||
* http://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.test.autoconfigure.orm.jpa;
|
||||
|
||||
import javax.persistence.EntityManagerFactory;
|
||||
|
||||
import org.springframework.boot.autoconfigure.AutoConfigureAfter;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
|
||||
import org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
/**
|
||||
* Auto-configuration for {@link TestEntityManager}.
|
||||
*
|
||||
* @author Phillip Webb
|
||||
* @see AutoConfigureTestEntityManager
|
||||
*/
|
||||
@Configuration
|
||||
@ConditionalOnClass({ EntityManagerFactory.class })
|
||||
@AutoConfigureAfter(HibernateJpaAutoConfiguration.class)
|
||||
class TestEntityManagerAutoConfiguration {
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean
|
||||
public TestEntityManager testEntityManager(
|
||||
EntityManagerFactory entityManagerFactory) {
|
||||
return new TestEntityManager(entityManagerFactory);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,20 @@
|
|||
/*
|
||||
* Copyright 2012-2016 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
|
||||
*
|
||||
* http://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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Auto-configuration for Data JPA tests.
|
||||
*/
|
||||
package org.springframework.boot.test.autoconfigure.orm.jpa;
|
|
@ -0,0 +1,95 @@
|
|||
/*
|
||||
* Copyright 2012-2016 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
|
||||
*
|
||||
* http://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.test.autoconfigure.orm.jpa;
|
||||
|
||||
import javax.sql.DataSource;
|
||||
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.junit.rules.ExpectedException;
|
||||
import org.junit.runner.RunWith;
|
||||
|
||||
import org.springframework.beans.factory.NoSuchBeanDefinitionException;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.test.context.junit4.SpringRunner;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* Integration tests for {@link DataJpaTest}.
|
||||
*
|
||||
* @author Phillip Webb
|
||||
*/
|
||||
@RunWith(SpringRunner.class)
|
||||
@DataJpaTest
|
||||
public class DataJpaTestIntegrationTests {
|
||||
|
||||
@Rule
|
||||
public ExpectedException thrown = ExpectedException.none();
|
||||
|
||||
@Autowired
|
||||
private TestEntityManager entities;
|
||||
|
||||
@Autowired
|
||||
private ExampleRepository repository;
|
||||
|
||||
@Autowired
|
||||
private DataSource dataSource;
|
||||
|
||||
@Autowired
|
||||
private ApplicationContext applicationContext;
|
||||
|
||||
@Test
|
||||
public void testEntityManager() throws Exception {
|
||||
ExampleEntity entity = this.entities.persist(new ExampleEntity("spring", "123"));
|
||||
this.entities.flush();
|
||||
Object id = this.entities.getId(entity);
|
||||
ExampleEntity found = this.entities.find(ExampleEntity.class, id);
|
||||
assertThat(found.getName()).isEqualTo("spring");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testEntityManagerPersistAndGetId() throws Exception {
|
||||
Long id = this.entities.persistAndGetId(new ExampleEntity("spring", "123"),
|
||||
Long.class);
|
||||
assertThat(id).isNotNull();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRepository() throws Exception {
|
||||
this.entities.persist(new ExampleEntity("spring", "123"));
|
||||
this.entities.persist(new ExampleEntity("boot", "124"));
|
||||
this.entities.flush();
|
||||
ExampleEntity found = this.repository.findByReference("124");
|
||||
assertThat(found.getName()).isEqualTo("boot");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void replacesDefinedDatasourceWithEmbeddedDefault() throws Exception {
|
||||
String product = this.dataSource.getConnection().getMetaData()
|
||||
.getDatabaseProductName();
|
||||
assertThat(product).isEqualTo("H2");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void didNotInjectExampleComponent() throws Exception {
|
||||
this.thrown.expect(NoSuchBeanDefinitionException.class);
|
||||
this.applicationContext.getBean(ExampleComponent.class);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,74 @@
|
|||
/*
|
||||
* Copyright 2012-2016 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
|
||||
*
|
||||
* http://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.test.autoconfigure.orm.jpa;
|
||||
|
||||
import javax.sql.DataSource;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.jdbc.EmbeddedDatabaseConnection;
|
||||
import org.springframework.boot.test.autoconfigure.orm.jpa.AutoConfigureTestDatabase.Replace;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.test.context.junit4.SpringRunner;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* Integration tests for {@link DataJpaTest}.
|
||||
*
|
||||
* @author Phillip Webb
|
||||
*/
|
||||
@RunWith(SpringRunner.class)
|
||||
@DataJpaTest
|
||||
@AutoConfigureTestDatabase(replace = Replace.AUTO_CONFIGURED, connection = EmbeddedDatabaseConnection.HSQL)
|
||||
public class DataJpaTestWithAutoConfigureTestDatabaseReplaceAutoConfiguredIntegrationTests {
|
||||
|
||||
@Autowired
|
||||
private TestEntityManager entities;
|
||||
|
||||
@Autowired
|
||||
private ExampleRepository repository;
|
||||
|
||||
@Autowired
|
||||
private DataSource dataSource;
|
||||
|
||||
@Test
|
||||
public void testRepository() throws Exception {
|
||||
this.entities.persist(new ExampleEntity("spring", "123"));
|
||||
this.entities.persist(new ExampleEntity("boot", "124"));
|
||||
this.entities.flush();
|
||||
ExampleEntity found = this.repository.findByReference("124");
|
||||
assertThat(found.getName()).isEqualTo("boot");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void replacesAutoConfiguredDataSource() throws Exception {
|
||||
String product = this.dataSource.getConnection().getMetaData()
|
||||
.getDatabaseProductName();
|
||||
assertThat(product).startsWith("HSQL");
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@EnableAutoConfiguration // Will auto-configure H2
|
||||
static class Config {
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,66 @@
|
|||
/*
|
||||
* Copyright 2012-2016 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
|
||||
*
|
||||
* http://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.test.autoconfigure.orm.jpa;
|
||||
|
||||
import javax.sql.DataSource;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.test.autoconfigure.orm.jpa.AutoConfigureTestDatabase.Replace;
|
||||
import org.springframework.test.context.junit4.SpringRunner;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* Integration tests for {@link DataJpaTest}.
|
||||
*
|
||||
* @author Phillip Webb
|
||||
*/
|
||||
@RunWith(SpringRunner.class)
|
||||
@DataJpaTest
|
||||
@AutoConfigureTestDatabase(replace = Replace.AUTO_CONFIGURED)
|
||||
public class DataJpaTestWithAutoConfigureTestDatabaseReplaceAutoConfiguredWithoutOverrideIntegrationTests {
|
||||
|
||||
@Autowired
|
||||
private TestEntityManager entities;
|
||||
|
||||
@Autowired
|
||||
private ExampleRepository repository;
|
||||
|
||||
@Autowired
|
||||
private DataSource dataSource;
|
||||
|
||||
@Test
|
||||
public void testRepository() throws Exception {
|
||||
this.entities.persist(new ExampleEntity("spring", "123"));
|
||||
this.entities.persist(new ExampleEntity("boot", "124"));
|
||||
this.entities.flush();
|
||||
ExampleEntity found = this.repository.findByReference("124");
|
||||
assertThat(found.getName()).isEqualTo("boot");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void usesDefaultEmbeddedDatabase() throws Exception {
|
||||
String product = this.dataSource.getConnection().getMetaData()
|
||||
.getDatabaseProductName();
|
||||
// @AutoConfigureTestDatabase would use H2 but HSQL is manually defined
|
||||
assertThat(product).startsWith("HSQL");
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,84 @@
|
|||
/*
|
||||
* Copyright 2012-2016 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
|
||||
*
|
||||
* http://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.test.autoconfigure.orm.jpa;
|
||||
|
||||
import javax.sql.DataSource;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.jdbc.EmbeddedDatabaseConnection;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseBuilder;
|
||||
import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseType;
|
||||
import org.springframework.test.context.junit4.SpringRunner;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* Integration tests for {@link DataJpaTest}.
|
||||
*
|
||||
* @author Phillip Webb
|
||||
*/
|
||||
@RunWith(SpringRunner.class)
|
||||
@DataJpaTest
|
||||
@AutoConfigureTestDatabase(connection = EmbeddedDatabaseConnection.HSQL)
|
||||
public class DataJpaTestWithAutoConfigureTestDatabaseReplaceExplicitIntegrationTests {
|
||||
|
||||
@Autowired
|
||||
private TestEntityManager entities;
|
||||
|
||||
@Autowired
|
||||
private ExampleRepository repository;
|
||||
|
||||
@Autowired
|
||||
private DataSource dataSource;
|
||||
|
||||
@Test
|
||||
public void testRepository() throws Exception {
|
||||
this.entities.persist(new ExampleEntity("spring", "123"));
|
||||
this.entities.persist(new ExampleEntity("boot", "124"));
|
||||
this.entities.flush();
|
||||
ExampleEntity found = this.repository.findByReference("124");
|
||||
assertThat(found.getName()).isEqualTo("boot");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void replacesDefinedDatasourceWithExplicit() throws Exception {
|
||||
// H2 is explicitly defined by HSQL is the override
|
||||
String product = this.dataSource.getConnection().getMetaData()
|
||||
.getDatabaseProductName();
|
||||
assertThat(product).startsWith("HSQL");
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@EnableAutoConfiguration
|
||||
static class Config {
|
||||
|
||||
@Bean
|
||||
public DataSource dataSource() {
|
||||
EmbeddedDatabaseBuilder builder = new EmbeddedDatabaseBuilder()
|
||||
.setType(EmbeddedDatabaseType.H2);
|
||||
return builder.build();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,66 @@
|
|||
/*
|
||||
* Copyright 2012-2016 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
|
||||
*
|
||||
* http://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.test.autoconfigure.orm.jpa;
|
||||
|
||||
import javax.sql.DataSource;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.test.autoconfigure.orm.jpa.AutoConfigureTestDatabase.Replace;
|
||||
import org.springframework.test.context.junit4.SpringRunner;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* Integration tests for {@link DataJpaTest}.
|
||||
*
|
||||
* @author Phillip Webb
|
||||
*/
|
||||
@RunWith(SpringRunner.class)
|
||||
@DataJpaTest
|
||||
@AutoConfigureTestDatabase(replace = Replace.NONE)
|
||||
public class DataJpaTestWithAutoConfigureTestDatabaseReplaceNoneIntegrationTests {
|
||||
|
||||
@Autowired
|
||||
private TestEntityManager entities;
|
||||
|
||||
@Autowired
|
||||
private ExampleRepository repository;
|
||||
|
||||
@Autowired
|
||||
private DataSource dataSource;
|
||||
|
||||
@Test
|
||||
public void testRepository() throws Exception {
|
||||
this.entities.persist(new ExampleEntity("spring", "123"));
|
||||
this.entities.persist(new ExampleEntity("boot", "124"));
|
||||
this.entities.flush();
|
||||
ExampleEntity found = this.repository.findByReference("124");
|
||||
assertThat(found.getName()).isEqualTo("boot");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void usesDefaultEmbeddedDatabase() throws Exception {
|
||||
// HSQL is explicitly defined and should not be replaced
|
||||
String product = this.dataSource.getConnection().getMetaData()
|
||||
.getDatabaseProductName();
|
||||
assertThat(product).startsWith("HSQL");
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,29 @@
|
|||
/*
|
||||
* Copyright 2012-2016 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
|
||||
*
|
||||
* http://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.test.autoconfigure.orm.jpa;
|
||||
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
/**
|
||||
* Example component used with {@link DataJpaTest} tests.
|
||||
*
|
||||
* @author Phillip Webb
|
||||
*/
|
||||
@Component
|
||||
public class ExampleComponent {
|
||||
|
||||
}
|
|
@ -0,0 +1,41 @@
|
|||
/*
|
||||
* Copyright 2012-2016 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
|
||||
*
|
||||
* http://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.test.autoconfigure.orm.jpa;
|
||||
|
||||
import javax.sql.DataSource;
|
||||
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseBuilder;
|
||||
import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseType;
|
||||
|
||||
/**
|
||||
* Example {@link SpringBootApplication} used with {@link DataJpaTest} tests.
|
||||
*
|
||||
* @author Phillip Webb
|
||||
*/
|
||||
@SpringBootApplication
|
||||
public class ExampleDataJpaApplication {
|
||||
|
||||
@Bean
|
||||
public DataSource dataSource() {
|
||||
EmbeddedDatabaseBuilder builder = new EmbeddedDatabaseBuilder()
|
||||
.setType(EmbeddedDatabaseType.HSQL);
|
||||
return builder.build();
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,56 @@
|
|||
/*
|
||||
* Copyright 2012-2016 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
|
||||
*
|
||||
* http://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.test.autoconfigure.orm.jpa;
|
||||
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.GeneratedValue;
|
||||
import javax.persistence.Id;
|
||||
|
||||
/**
|
||||
* Example entity used with {@link DataJpaTest} tests.
|
||||
*
|
||||
* @author Phillip Webb
|
||||
*/
|
||||
@Entity
|
||||
public class ExampleEntity {
|
||||
|
||||
@Id
|
||||
@GeneratedValue
|
||||
private Long id;
|
||||
|
||||
private String name;
|
||||
|
||||
private String reference;
|
||||
|
||||
protected ExampleEntity() {
|
||||
}
|
||||
|
||||
public ExampleEntity(String name, String reference) {
|
||||
super();
|
||||
this.name = name;
|
||||
this.reference = reference;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return this.name;
|
||||
}
|
||||
|
||||
public String getReference() {
|
||||
return this.reference;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,30 @@
|
|||
/*
|
||||
* Copyright 2012-2016 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
|
||||
*
|
||||
* http://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.test.autoconfigure.orm.jpa;
|
||||
|
||||
import org.springframework.data.repository.Repository;
|
||||
|
||||
/**
|
||||
* Example repository used with {@link DataJpaTest} tests.
|
||||
*
|
||||
* @author Phillip Webb
|
||||
*/
|
||||
public interface ExampleRepository extends Repository<ExampleEntity, Long> {
|
||||
|
||||
ExampleEntity findByReference(String reference);
|
||||
|
||||
}
|
|
@ -0,0 +1,241 @@
|
|||
/*
|
||||
* Copyright 2012-2016 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
|
||||
*
|
||||
* http://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.test.autoconfigure.orm.jpa;
|
||||
|
||||
import javax.persistence.EntityManager;
|
||||
import javax.persistence.EntityManagerFactory;
|
||||
import javax.persistence.PersistenceUnitUtil;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.junit.rules.ExpectedException;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.MockitoAnnotations;
|
||||
|
||||
import org.springframework.orm.jpa.EntityManagerHolder;
|
||||
import org.springframework.transaction.support.TransactionSynchronizationManager;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.mockito.BDDMockito.given;
|
||||
import static org.mockito.Mockito.verify;
|
||||
|
||||
/**
|
||||
* Tests for {@link TestEntityManager}.
|
||||
*
|
||||
* @author Phillip Webb
|
||||
*/
|
||||
public class TestEntityManagerTests {
|
||||
|
||||
@Rule
|
||||
public ExpectedException thrown = ExpectedException.none();
|
||||
|
||||
@Mock
|
||||
private EntityManagerFactory entityManagerFactory;
|
||||
|
||||
@Mock
|
||||
private EntityManager entityManager;
|
||||
|
||||
@Mock
|
||||
private PersistenceUnitUtil persistenceUnitUtil;
|
||||
|
||||
private TestEntityManager testEntityManager;
|
||||
|
||||
@Before
|
||||
public void setup() {
|
||||
MockitoAnnotations.initMocks(this);
|
||||
this.testEntityManager = new TestEntityManager(this.entityManagerFactory);
|
||||
given(this.entityManagerFactory.getPersistenceUnitUtil())
|
||||
.willReturn(this.persistenceUnitUtil);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void createWhenEntityManagerIsNullShouldThrowException() throws Exception {
|
||||
this.thrown.expect(IllegalArgumentException.class);
|
||||
this.thrown.expectMessage("EntityManagerFactory must not be null");
|
||||
new TestEntityManager(null);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void persistAndGetIdShouldPersistAndGetId() throws Exception {
|
||||
bindEntityManager();
|
||||
TestEntity entity = new TestEntity();
|
||||
given(this.persistenceUnitUtil.getIdentifier(entity)).willReturn(null, 123);
|
||||
Object result = this.testEntityManager.persistAndGetId(entity);
|
||||
verify(this.entityManager).persist(entity);
|
||||
assertThat(result).isEqualTo(123);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void persistAndGetIdForTypeShouldPersistAndGetId() throws Exception {
|
||||
bindEntityManager();
|
||||
TestEntity entity = new TestEntity();
|
||||
given(this.persistenceUnitUtil.getIdentifier(entity)).willReturn(null, 123);
|
||||
Integer result = this.testEntityManager.persistAndGetId(entity, Integer.class);
|
||||
verify(this.entityManager).persist(entity);
|
||||
assertThat(result).isEqualTo(123);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void persistShouldPersist() throws Exception {
|
||||
bindEntityManager();
|
||||
TestEntity entity = new TestEntity();
|
||||
TestEntity result = this.testEntityManager.persist(entity);
|
||||
verify(this.entityManager).persist(entity);
|
||||
assertThat(result).isSameAs(entity);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void persistWhenAlreadyHasIdShouldThrowException() throws Exception {
|
||||
bindEntityManager();
|
||||
TestEntity entity = new TestEntity();
|
||||
given(this.persistenceUnitUtil.getIdentifier(entity)).willReturn(123);
|
||||
this.thrown.expect(IllegalStateException.class);
|
||||
this.thrown.expectMessage(
|
||||
"Entity " + TestEntity.class.getName() + " already has an ID");
|
||||
this.testEntityManager.persistAndGetId(entity, Integer.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void persistAndFlushShouldPersistAndFlush() throws Exception {
|
||||
bindEntityManager();
|
||||
TestEntity entity = new TestEntity();
|
||||
TestEntity result = this.testEntityManager.persistAndFlush(entity);
|
||||
verify(this.entityManager).persist(entity);
|
||||
verify(this.entityManager).flush();
|
||||
assertThat(result).isSameAs(entity);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void persistFlushFindShouldPersistAndFlushAndFind() throws Exception {
|
||||
bindEntityManager();
|
||||
TestEntity entity = new TestEntity();
|
||||
TestEntity found = new TestEntity();
|
||||
given(this.persistenceUnitUtil.getIdentifier(entity)).willReturn(null, 123);
|
||||
given(this.entityManager.find(TestEntity.class, 123)).willReturn(found);
|
||||
TestEntity result = this.testEntityManager.persistFlushFind(entity);
|
||||
verify(this.entityManager).persist(entity);
|
||||
verify(this.entityManager).flush();
|
||||
assertThat(result).isSameAs(found);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void mergeShouldMerge() throws Exception {
|
||||
bindEntityManager();
|
||||
TestEntity entity = new TestEntity();
|
||||
given(this.entityManager.merge(entity)).willReturn(entity);
|
||||
TestEntity result = this.testEntityManager.merge(entity);
|
||||
verify(this.entityManager).merge(entity);
|
||||
assertThat(result).isSameAs(entity);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void removeShouldRemove() throws Exception {
|
||||
bindEntityManager();
|
||||
TestEntity entity = new TestEntity();
|
||||
this.testEntityManager.remove(entity);
|
||||
verify(this.entityManager).remove(entity);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void findShouldFind() throws Exception {
|
||||
bindEntityManager();
|
||||
TestEntity entity = new TestEntity();
|
||||
given(this.entityManager.find(TestEntity.class, 123)).willReturn(entity);
|
||||
TestEntity result = this.testEntityManager.find(TestEntity.class, 123);
|
||||
assertThat(result).isSameAs(entity);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void flushShouldFlush() throws Exception {
|
||||
bindEntityManager();
|
||||
this.testEntityManager.flush();
|
||||
verify(this.entityManager).flush();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void refreshShouldRefresh() throws Exception {
|
||||
bindEntityManager();
|
||||
TestEntity entity = new TestEntity();
|
||||
this.testEntityManager.refresh(entity);
|
||||
verify(this.entityManager).refresh(entity);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void clearShouldClear() throws Exception {
|
||||
bindEntityManager();
|
||||
this.testEntityManager.clear();
|
||||
verify(this.entityManager).clear();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void detachShouldDetach() throws Exception {
|
||||
bindEntityManager();
|
||||
TestEntity entity = new TestEntity();
|
||||
this.testEntityManager.detach(entity);
|
||||
verify(this.entityManager).detach(entity);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getIdForTypeShouldGetId() throws Exception {
|
||||
TestEntity entity = new TestEntity();
|
||||
given(this.persistenceUnitUtil.getIdentifier(entity)).willReturn(123);
|
||||
Integer result = this.testEntityManager.getId(entity, Integer.class);
|
||||
assertThat(result).isEqualTo(123);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getIdForTypeWhenTypeIsWrongShouldThrowException() throws Exception {
|
||||
TestEntity entity = new TestEntity();
|
||||
given(this.persistenceUnitUtil.getIdentifier(entity)).willReturn(123);
|
||||
this.thrown.expectMessage("ID missmatch Object of class [java.lang.Integer] "
|
||||
+ "must be an instance of class java.lang.Long");
|
||||
this.testEntityManager.getId(entity, Long.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getIdShouldGetId() throws Exception {
|
||||
TestEntity entity = new TestEntity();
|
||||
given(this.persistenceUnitUtil.getIdentifier(entity)).willReturn(123);
|
||||
Object result = this.testEntityManager.getId(entity);
|
||||
assertThat(result).isEqualTo(123);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getEntityManagerShouldGetEntityManager() throws Exception {
|
||||
bindEntityManager();
|
||||
assertThat(this.testEntityManager.getEntityManager())
|
||||
.isEqualTo(this.entityManager);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getEntityManagerWhenNotSetShouldThrowException() throws Exception {
|
||||
this.thrown.expect(IllegalStateException.class);
|
||||
this.thrown.expectMessage("No transactional EnitiyManager found");
|
||||
this.testEntityManager.getEntityManager();
|
||||
}
|
||||
|
||||
private void bindEntityManager() {
|
||||
EntityManagerHolder holder = new EntityManagerHolder(this.entityManager);
|
||||
TransactionSynchronizationManager.bindResource(this.entityManagerFactory, holder);
|
||||
}
|
||||
|
||||
static class TestEntity {
|
||||
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in New Issue