Java 为什么实体管理器在spring启动测试父级中不为null,但在存储库中为null?

Java 为什么实体管理器在spring启动测试父级中不为null,但在存储库中为null?,java,spring-boot,jpa,testing,spring-data-jpa,Java,Spring Boot,Jpa,Testing,Spring Data Jpa,我在父测试类中有实体管理器 @RunWith(SpringRunner.class) @SpringBootTest( properties = { "spring.profiles.active=test", "spring.config.name=app-test"}) public abstract class ViewerTestBase extends DbBuilderImpl { @Autowired EntityManag

我在父测试类中有实体管理器

@RunWith(SpringRunner.class)
@SpringBootTest(
    properties = {
            "spring.profiles.active=test",
            "spring.config.name=app-test"})
public abstract class ViewerTestBase extends DbBuilderImpl {

@Autowired EntityManager em;
这里的实体管理器正常。DbBuilder设置测试数据。 在@repository中为空

@Repository public class PaymentTransactionDao {
@Autowired EntityManager em;
导致测试用例失败

实体管理器映射到h2数据库进行测试

持久性配置类是boiler plate

@Configration
@EnableTransactionManagement
public class PersistenceConfig {

  @Bean
  public LocalContainerEntityManagerFactoryBean entityManagerFactory(EntityManagerFactoryBuilder builder) {
    LocalContainerEntityManagerFactoryBean em = builder.dataSource(viewerDataSource())
            .packages("viewer.model")
            .persistenceUnit("viewer")
            .build();
    return em;
  }

  @Bean
  public PlatformTransactionManager transactionManager(
        EntityManagerFactory viewerEntityManagerFactory) {
    return new JpaTransactionManager(pspEntityManagerFactory);
  }

  @Bean
  @Primary
  @ConfigurationProperties(prefix = "viewer.dbo.datasource")
  public DataSource viewerDataSource() {
    return DataSourceBuilder.create().build();
  }

  @Bean
  @ConfigurationProperties(prefix = "viewer.auth.datasource")
  public DataSource authDataSource() {
    return DataSourceBuilder.create().build();
  }
使用spring boot starter jpa进行设置

compile group: 'org.springframework.boot', name: 'spring-boot-starter-web'
compile("org.springframework.boot:spring-boot-devtools")
compile group: 'org.springframework.boot', name: 'spring-boot-starter-data-jpa'

testCompile group: 'junit', name: 'junit', version: '4.12'
testCompile group: 'com.h2database', name: 'h2'
testCompile('org.springframework.boot:spring-boot-starter-test')
testCompile group: 'org.springframework.boot', name: 'spring-boot-test'
testCompile group: 'org.springframework.boot', name: 'spring-boot-test-autoconfigure'

为了将EntityManager置于持久性上下文中,请更改:

@Autowired  
private EntityManager entityManager;

持久性上下文是一组实体实例,其中对于任何持久性实体标识,都有一个唯一的实体实例。在持久性上下文中,实体实例及其生命周期由特定的实体管理器管理。此上下文的范围可以是事务,也可以是扩展的工作单元


通过使用构造函数注入解决了这个问题

更改@Repository构造函数

public class ViewItemDao {
  @PersistenceContext
  protected EntityManager em;
  public ViewItemDao(EntityManager em) {
    this.em = em;
  }
变更测试。注意,实体管理器被注入到测试类中,只使用@RunWith(SpringRunner.class)和@SpringBootTest

@Test
public void testQueryId() throws InvalidSearchParameterException, SearchFailureException {
    generateTransaction("639051cc-4b19-4383-9c9a-89a80cd2a2f9");

    ViewItemDao viewItemDao = new ViewItemDao(em);

我确实将@Autowired更改为@PersistenceContext,但没有注意到差异。

我猜类加载器是不同的。
@Test
public void testQueryId() throws InvalidSearchParameterException, SearchFailureException {
    generateTransaction("639051cc-4b19-4383-9c9a-89a80cd2a2f9");

    ViewItemDao viewItemDao = new ViewItemDao(em);