有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

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

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

@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'

共 (2) 个答案

  1. # 1 楼答案

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

    @Autowired  
    private EntityManager entityManager;
    

    @PersistenceContext
    private EntityManager entityManager;
    

    A persistence context is a set of entity instances in which for any persistent entity identity there is a unique entity instance. Within the persistence context, the entity instances and their lifecycle is managed by a particular entity manager. The scope of this context can either be the transaction, or an extended unit of work.

    Official documentation hibernate definitions

  2. # 2 楼答案

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

    更改@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,但没有注意到任何差异