问题描述
我正在研究 Spring JPA 集成,并在尝试使用 EntityManager
注释自动装配 @Autowired
时提出了奇怪的行为。
我有一个没有 Spring Boot 上下文支持的 Spring 测试:
@ExtendWith(SpringExtension.class)
class JpaTransactionScopedPersistentContextTests {
@Configuration
@ComponentScan(basePackages = {
"packages"
})
static class TestConfiguration {}
@Autowired
private EntityAService entityAService;
@Test
void testEntityManagerWithoutTransaction () {
EntityA entityA = new EntityA();
entityAService.save(entityA);
}
}
服务定义如下:
@Service
public class EntityAService {
// @PersistenceContext - this works
@Autowired // this fails
private EntityManager entityManager;
public EntityA save (EntityA entityA) {
return entityManager.merge(entityA);
}
@Transactional
public EntityA saveInTransaction (EntityA entityA) {
return entityManager.merge(entityA);
}
}
我有以下 JPA 配置:
@EnableTransactionManagement
@Configuration
public class ConfigurationA {
@Bean
public DataSource dataSourceWithEmbeddedDatabaseBuilder () throws sqlException {
return new EmbeddedDatabaseBuilder()
.setName("test")
.setType(EmbeddedDatabaseType.H2)
.addScripts("classpath:/schema.sql")
.addScripts("classpath:/data.sql")
.build();
}
@Bean
public LocalContainerEntityManagerfactorybean entityManagerFactory (DataSource dataSource) {
LocalContainerEntityManagerfactorybean entityManagerfactorybean =
new LocalContainerEntityManagerfactorybean();
entityManagerfactorybean.setDataSource(dataSource);
entityManagerfactorybean.setPackagesToScan("packages");
JpavendorAdapter vendorAdapter = new HibernateJpavendorAdapter();
entityManagerfactorybean.setJpavendorAdapter(vendorAdapter);
return entityManagerfactorybean;
}
@Bean
public PlatformTransactionManager jpaTransactionManager (EntityManagerFactory entityManagerFactory) {
return new JpaTransactionManager(entityManagerFactory);
}
}
Spring 抛出错误:
No qualifying bean of type 'javax.persistence.EntityManager' available: expected at least 1 bean which qualifies as autowire candidate.
为什么?
解决方法
经过几个小时的调试,我找到了原因。
这个:
@Autowired
private EntityManager entityManager;
仅当您有 @EnableJpaRepositories
注释时才有效。
例如:
@EnableJpaRepositories
@Configuration
public class ConfigurationA {}
也就是说,EntityManager
的自动装配是 Spring Data JPA 模块提供的一个特性。它不是由通常的 Spring JPA 集成提供的。