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

阿奎利安和飞行方式使用不同版本的H2内存

桓瀚
2023-03-14

我正在尝试创建一个JPA助手,它最终将变成一个罐子并用于其他项目。我想将集成测试添加到此项目中,因此我添加了一个 TestEntityTestService 类(这些类是指数据库架构中的一个简单的 TEST 表)。

目标是用H2创建内存数据库,用Arquillian在容器中运行测试,用Flyway创建/填充测试数据库。Flyway由@ApplicationScoped类的监听器触发。

但是,每当我触发集成测试时,该测试似乎都能正常工作,直到调用count(*)查询。此时,Hibernate抱怨架构(刚刚在Flyway中创建)不存在:架构“DB”不存在

有很多日志,但亮点如下:

    < li >测试Glassfish服务器已启动 < li >Hibernate开始 < ul > < li >它还没有抱怨任何事情 < li >如果< code > hibernate . hbm 2 DDL . auto 设置为< code>validate,则它会报告在Flyway中创建的表不存在(< code > Schema-validation:missing table[DB .测试])
  • 它表示两个脚本都成功执行
  • 架构“DB”不存在

我认为飞航和实体管理器正在与数据库的不同实例进行通信。Flyway 所做的更改不会以实体管理器可以看到的方式保存。

  • 确保EntityManagerFlyway正在与同一数据库通信。
    • 名称完全相同(请参见persistence.xmlEntityManagerFactory ),我尝试添加/删除各种
    • 在Flyway迁移代码中输入语法错误会导致测试因SQL错误而失败。
      • 如果在SQL代码中放入重复语句(例如:第二次创建表或模式),也会发生同样的情况
      • 即:jdbc:h2:mem:test;DB_CLOSE_DELAY=-1;INIT=来自“类路径:创建.sql”的 RUNSCRIPT
      • 我知道脚本被触发了(因为添加错误会导致测试失败),但它仍然没有解决模式“DB”不存在的问题。
      • Schema'DB'不存在
      • 验证架构验证:缺少表[DB.TEST]
      • updatecreate-drop:表已创建,但Flyway中的数据丢失
        < li >这将在< code>C:\Users\
      • 阿奎利安持久性
        • 它看起来很棒,但我在公司网络上,他们还没有批准它
        • 这个项目不使用Spring任何东西
        // various "server startup" logs
        // ...
        // misc hibernate logs
        Apr 15, 2020 9:40:39 AM org.hibernate.jpa.internal.util.LogHelper logPersistenceUnitInformation
        INFO: HHH000204: Processing PersistenceUnitInfo [
            name: TestDS
            ...]
        // ...
        Loading Flyway Data
        8 [main] INFO org.flywaydb.core.internal.util.VersionPrinter - Flyway Community Edition 5.0.7 by Boxfuse
        246 [main] INFO org.flywaydb.core.internal.database.DatabaseFactory - Database: jdbc:h2:mem:test (H2 1.4)
        354 [main] INFO org.flywaydb.core.internal.command.DbValidate - Successfully validated 2 migrations (execution time 00:00.028s)
        377 [main] INFO org.flywaydb.core.internal.schemahistory.JdbcTableSchemaHistory - Creating Schema History table: "PUBLIC"."flyway_schema_history"
        413 [main] INFO org.flywaydb.core.internal.command.DbMigrate - Current version of schema "PUBLIC": << Empty Schema >>
        415 [main] INFO org.flywaydb.core.internal.command.DbMigrate - Migrating schema "PUBLIC" to version 1 - CreateDatabase
        436 [main] INFO org.flywaydb.core.internal.command.DbMigrate - Migrating schema "PUBLIC" to version 2 - AddTestClasses
        449 [main] INFO org.flywaydb.core.internal.command.DbMigrate - Successfully applied 2 migrations to schema "PUBLIC" (execution time 00:00.078s)
        Apr 15, 2020 9:40:44 AM com.sun.enterprise.web.WebApplication start
        INFO: Loading application [test] at [/test]
        Apr 15, 2020 9:40:45 AM org.glassfish.deployment.admin.DeployCommand execute
        INFO: test was successfully deployed in 7,649 milliseconds.
        Apr 15, 2020 9:40:45 AM org.hibernate.hql.internal.QueryTranslatorFactoryInitiator initiateService
        INFO: HHH000397: Using ASTQueryTranslatorFactory
        Hibernate: 
            select
                count(testobject0_.id) as col_0_0_ 
            from
                DB.TEST testobject0_ 
            where
                1=1
        Apr 15, 2020 9:40:45 AM org.hibernate.engine.jdbc.spi.SqlExceptionHelper logExceptions
        WARN: SQL Error: 30000, SQLState: 42Y07
        Apr 15, 2020 9:40:45 AM org.hibernate.engine.jdbc.spi.SqlExceptionHelper logExceptions
        ERROR: Schema 'DB' does not exist
        
        // stack trace
        / ...
        
        @RunWith(Arquillian.class)
        public class ProviderTest {
        
            @Deployment
            public static JavaArchive createDeployment() {
                JavaArchive jar = ShrinkWrap.create(JavaArchive.class)
                        .addClasses(
                                TestObject.class,
                                TestService.class,
                                QueryValuesProviderImpl.class,
                                CriteriaQueryProviderFactory.class,
                                EntityManagerFactory.class
                                )
                        .addClass(FlywayDataLoader.class)
                        .addAsResource("META-INF/persistence.xml")
                        .addAsManifestResource(new ByteArrayAsset(new byte[0]), ArchivePaths.create("beans.xml"));
                System.out.println(jar.toString(true));
                return jar;
            }
        
            @Inject
            private TestService testService;
        
            @Test
            public void testGetTestResource() {
                List<TestObject> data = testService.getTestObjects(new QueryValues());
        
                assertNotNull(data);
                assertEquals(2, data.size());
            }
        }
        
        @ApplicationScoped
        public class FlywayDataLoader {
        
            private static final String JDBC_URL = "jdbc:h2:mem:test;DB_CLOSE_DELAY=-1";
            private static boolean initialized = false;
        
            public static void setup(
                    @Observes @Initialized(ApplicationScoped.class) final Object event
            ) {
                if (!initialized) {
                    System.out.println("Loading Flyway Data");
                    Flyway flyway = new Flyway();
                    flyway.setDataSource(JDBC_URL, "sa", "");
                    flyway.setBaselineOnMigrate(true);
                    flyway.migrate();
        
                    initialized = true;
                }
            }
        }
        

        它被分成两个文件(一个用于创建架构/表,另一个用于插入实际数据)。这些文件位于 /resources/db.migration/ 文件夹中,分别命名为 V1__CreateDatabase.sqlV2__AddTestClasses.sql

        CREATE SCHEMA DB;
        
        create table DB.TEST
        (
            ID INT auto_increment
                constraint PK_REQUEST_AUDIT
                    primary key,
            FN VARCHAR2(256 char) default NULL not null,
            LN VARCHAR2(256 char) default NULL not null,
            BD TIMESTAMP default SYSDATE not null
        )
        ;
        
        insert into DB.TEST (FN, LN, BD) VALUES ('Alice', 'Zyl', PARSEDATETIME('1985-03-13','yyyy-MM-dd','en'));
        insert into DB.TEST (FN, LN, BD) VALUES ('Bart', 'Young', PARSEDATETIME('1988-03-25','yyyy-MM-dd','en'));
        

        此处使用的< code>unitName与< code>persistence.xml中使用的持久性单元名称相匹配。这里使用的JDBC连接字符串与Flyway Java脚本中使用的相同。

        public class EntityManagerFactory {
        
            @PersistenceUnit(unitName="TestDS")
            private javax.persistence.EntityManagerFactory emFactory;
        
            @Produces
            @Default
            @RequestScoped
            public EntityManager create() {
                return emFactory.createEntityManager();
            }
        
            public void dispose(@Disposes @Default EntityManager em){
                if(em.isOpen()){
                    em.close();
                }
            }
        
        }
        
        <?xml version="1.0" encoding="UTF-8"?>
        <persistence xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                     version="2.1" xmlns="http://xmlns.jcp.org/xml/ns/persistence"
                     xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence http://xmlns.jcp.org/xml/ns/persistence/persistence_2_1.xsd">
            <persistence-unit name="TestDS" transaction-type="RESOURCE_LOCAL">
                <provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>
                <class>myproject.beans.TestObject</class>
        
                <properties>
                    <!-- Configuring JDBC properties -->
                    <property name="javax.persistence.jdbc.url" value="jdbc:h2:mem:test;DB_CLOSE_DELAY=-1"/>
                    <property name="javax.persistence.jdbc.driver" value="org.h2.Driver"/>
                    <!-- Hibernate properties -->
                    <property name="hibernate.ddl-auto" value="none" />
                    <property name="hibernate.connection.user" value="sa" />
                    <property name="hibernate.archive.autodetection" value="class"/>
                    <property name="hibernate.format_sql" value="true"/>
                    <property name="hibernate.show_sql" value="true"/>
                </properties>
            </persistence-unit>
        </persistence>
        
        @RequestScoped
        public class TestService {
        
            @Inject
            private EntityManager em;
        
            @Inject
            private CriteriaQueryProviderFactory criteriaQueryProviderFactory;
        
            public List<TestObject> getTestObjects(QueryValues queryValues) {
                CriteriaQueryProvider<TestObject> criteriaQueryProvider = criteriaQueryProviderFactory.getFactory();
        
                CriteriaQuery<TestObject> criteriaQuery = criteriaQueryProvider.buildModifiedQuery(queryValues, TestObject.class);
                TypedQuery<TestObject> typedQuery = criteriaQueryProvider.addSecondaryModifiers(criteriaQuery, queryValues, TestObject.class);
        
                TypedQuery<Long> countQuery = criteriaQueryProvider.buildCountQuery(queryValues, TestObject.class);
        
                System.out.println(String.format("There are %d objects total!", countQuery.getSingleResult()));
        
                return typedQuery.getResultList();
            }
        }
        

共有1个答案

张华池
2023-03-14

我发现将Flyway与Hibernate集成的最佳方式是使用< code > org . Hibernate . integrator . SPI . integrator 的实现:https://docs . JBoss . org/Hibernate/ORM/5.4/javadocs/org/Hibernate/integrator/SPI/integrator . html。该接口有两个方法,即< code>integrate和< code > discrete 。如果您将运行Flyway的代码放入实现的< code>integrate方法中,一切都会正常工作。Hibernate从Java标准API加载服务加载器机制的< code > org . hibernate . integrator . SPI . integrator 实现,因此您必须创建一个文件< code > META-INF/services/org . hibernate . integrator . SPI . integrator ,其中包含您的实现的完全限定类名。

最好的

延斯

 类似资料:
  • 如何模拟处于注入链中的类?例如,ServiceA注入ServiceB,后者注入ServiceC(ServiceA- 在Arquillian测试中,我需要测试ServiceA和mock ServiceC,这在我的注入链中被调用。 我想要的是(服务)- 我怎样才能用阿奎利安做到这一点?

  • 问题内容: 是否可以在同一台计算机上安装不同版本的NodeJS? 问题答案: 您可以使用几种节点管理器来实现此目的,但是最受欢迎的是: 虚拟机 ñ

  • 本文向大家介绍Android同时安装Release和Debug版本的方法,包括了Android同时安装Release和Debug版本的方法的使用技巧和注意事项,需要的朋友参考一下 一般项目做到后期,在测试的时候,需要在测试版本和正式版本之间进行频繁的切换,怎么办呢?土豪的话可以考虑使用两台机器,同时测试,然而为了方便测试,节约成本,最好的办法当然是在同一台机器上安装不同的版本。 然而,原则上来说,

  • 问题内容: 我们将更新创建从Java 7到Java 8的构建的CI系统。稍后,我们希望将项目一个接一个地迁移到Java 8。当然,我们希望能够为仍使用Java 7的旧版本创建错误修正版本。 如果我们将构建相同的源,目标版本和源版本从JDK 7转移到JDK 8,我们是否可以确定不会出现任何问题?我们在开发机器上进行了测试,没有任何问题。 在此之前,我们还将逐步将部署服务器从JRE 7更新到JRE 8

  • 我正在尝试使用OMP运行矩阵乘法程序。我在串行和并行版本中得到了不同的输出。我正在尝试使用一个3*3矩阵进行测试。 我的并行代码是: 对于串行版本,我刚刚注释了该行: 我的并行版本的输出是: 起始矩阵 具有 12 个线程的多个示例初始化矩阵...线程 0 起始矩阵乘...线程 8 起始矩阵乘法...线程 6 起始矩阵乘...线程 9 起始矩阵乘法...线程 5 起始矩阵乘法...线程 1 起始矩阵

  • 问题内容: 我们正在使用JBoss 4.2.3,该版本又带有Hibernate的3.2.1.ga版本。我想使用支持JPA 2.0的Hibernate 3.5.1-FINAL。我一直在尝试通过将自己的hibernatejar放入WEB-INF / lib文件夹并在jboss- web.xml中为WAR创建自己的类加载器来使其工作 我也尝试过: 但是我遇到了很多问题,这是我目前坚持的例外情况: 由于最