Spring @Autowired EntityManager 失败

问题描述

我正在研究 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 集成提供的。