#java #spring #spring-boot #spring-data-jpa
#java #spring #весенняя загрузка #spring-data-jpa
Вопрос:
Я изучаю интеграцию Spring JPA и сталкиваюсь со странным поведением при попытке автоматического подключения EntityManager
с @Autowired
помощью аннотации.
У меня есть весенний тест, который не имеет поддержки контекста загрузки 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.
Почему?
Ответ №1:
После нескольких часов отладки кучи внутреннего кода Spring я нашел причину.
Это:
@Autowired
private EntityManager entityManager;
Работает только при наличии @EnableJpaRepositories
аннотации.
Например:
@EnableJpaRepositories
@Configuration
public class ConfigurationA {}
То есть автоматическое подключение — это EntityManager
функция, предоставляемая модулем Spring Data JPA. Это не предусмотрено обычной интеграцией Spring JPA.
Комментарии:
1. Вы можете использовать
@PersistenceContext
для вводаEntityManager
без использования Spring Data JPA. Это показано в справочной документации Spring Framework .