Сбой Spring @Autowired EntityManager

#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 .