当前位置: 首页 > 知识库问答 >
问题:

如何在JEE实体管理器中使用testcontainer中的数据源

鲍国兴
2023-03-14

在一个项目中,我们使用的不是Spring(其中有大量关于test容器的信息),而是一个相当古老的jboss版本6.4.0。带有Hibernate的EAP,我们不能改变它。测试框架是Junit4,在某种程度上是arquillian。

我试图改进集成测试,并希望至少在数据库测试设置中使用testcontainers。我知道如何启动testcontainer(在这种情况下是mysqlcontainer)以及如何运行现有的liquibase脚本。

我所坚持的是:如何使用数据源,我可以在这里从我启动的容器中获得

public DataSource getDataSource(MySQLContainer<?> mySQLContainer) {
    MysqlDataSource ds = new MysqlDataSource();
    ds.setUser(mySQLContainer.getUsername());
    ds.setPassword(mySQLContainer.getPassword());
    ds.setURL(mySQLContainer.getJdbcUrl());
    return ds;
}

创建实体管理器,然后将其注入现有Dao?应用程序中的Dao定义如下

@ApplicationScoped
public class MyDao {

    @Inject
    private EntityManager entityManager;

    protected EntityManager getEM() {
        return entityManager;
    }
}

共有1个答案

江礼骞
2023-03-14

您的JEE项目不使用Spring,但您只能将其用于数据源层的测试。

你需要的是:

  • 启动mysql作为docker容器
  • 应用DDL语句和liqbase创建表等。
  • 可能填充表
  • 并有权访问javax.persistence.EntityManager中的测试

下面是一个简化版本,让我们了解一下:

@DataJpaTest
@TestPropertySource(properties = {"spring.jpa.hibernate.ddl-auto=validate"})
@AutoConfigureTestDatabase(replace = AutoConfigureTestDatabase.Replace.NONE)
@ContextConfiguration(initializers = { MySqlLiquibaseBaseIT.Initializer.class })
@Testcontainers
public class MySqlLiquibaseBaseIT {

  @Container
  public static MySQLContainer<?> mysql = new MySQLContainer<>(
    DockerImageName
      .parse(MySQLContainer.NAME)
      .withTag("5.7.22"));

  @Configuration
  @EnableJpaRepositories
  @EntityScan
  static class Initializer implements ApplicationContextInitializer<ConfigurableApplicationContext> {
    @Override
    public void initialize(ConfigurableApplicationContext configurableApplicationContext) {
      TestPropertyValues.of(
        "spring.datasource.url=" + mysql.getJdbcUrl(),
        "spring.datasource.username=" + mysql.getUsername(),
        "spring.datasource.password=" + mysql.getPassword(),
        "spring.datasource.driver-class-name=" + mysql.getDriverClassName())
        .applyTo(configurableApplicationContext.getEnvironment());
    }

    @Bean
    public SpringLiquibase springLiquibase(DataSource dataSource) {
      SpringLiquibase liquibase = new SpringLiquibase();
      liquibase.setDropFirst(true);
      liquibase.setDataSource(dataSource);
      liquibase.setChangeLog("classpath:/db/changelog/db.changelog-master.yml");
      return liquibase;
    }
  }
}

实际上,我用容器做了很多有用的事情,比如:

  • mysql自定义配置

完整的MySqlLiquibaseBaseIT类可以在这里找到

在您的测试中,您可以直接扩展它并使用DataSourceEntityManager

public class ExampleEntityIT extends MySqlLiquibaseBaseIT {

  public static final long ENTITY_ID = 25L;

  @Autowired
  private DataSource dataSource;
  @Autowired
  private EntityManager entityManager;

  @Test
  public void injectedComponentsAreNotNull(){
    Assertions.assertNotNull(dataSource);
    Assertions.assertNotNull(entityManager);
  }
}
 类似资料:
  • 但问题是这将只锁定一行,而我想在计算总行数时锁定整个表(实体)。 请指教。

  • 否则,我将需要把我的大查询放在一个注释中。我更希望有更清楚的东西,而不是一个长的文本。

  • 我正在为Spring Data JPA存储库编写一个自定义实现。所以我有: = 我的问题是:在的实现中,我需要访问注入SpringData的实体管理器。如何得到它?我可以使用自动连接,但问题是这个存储库必须在设置多个持久性单元的应用程序中工作。因此,要告诉Spring我需要哪一个,我必须使用。然而,由于我的存储库是在可重用服务层中定义的,因此我不知道高级应用程序层将配置注入我的存储库中的持久化单元

  • 在我的DAO类中,假设我有实体管理器'em'是由实体管理器工厂制作的,之后的代码如下所示:- 当我执行上面的代码行时,在堆内存中创建了一个对象,并在其中存储了其实例变量“xyz”的值。 在第3行之后,如我们所知,carEntity对象进入托管状态。它将不会转到数据库,直到我刷新或提交事务。 那么实体管理器如何知道一个实体已经进入托管状态呢?执行后,是否为CarEntity创建了一个新对象?或者它在

  • 我试图实现搜索功能网格使用和条件。如果我给两个参数它给的结果。但是如果我想搜索只使用第一个字段,第二个是空的。它根据AND功能给出空数组。在这种情况下如何避免空参数。 如果一个参数为空,那么如何避免该参数,并根据该参数得到结果,而该参数不是空的。 会计控制员 会计服务 帐户存储库 AccountRepositoryCustomImpl Spring我是新来的。有谁能帮我,我需要在上面的代码中更改什

  • 问题内容: 我使用的是Hibernate事件监听器,喜欢在插入,删除和更新期间执行一些操作。现在,我想使用JPA侦听器执行此操作,因为如果我想从Hibernate迁移到任何其他JPA提供程序,则我的侦听器应该可以工作。Hibernate侦听器为我提供了从中获取事务并检查其提交还是回滚的功能。JPA侦听器仅向我提供实体对象。现在如何在JPA侦听器中获取事务或会话或实体管理器?提前致谢!!我正在使用J