【问题标题】:Junit Hibernate creates database schema multiple timesJunit Hibernate 多次创建数据库模式
【发布时间】:2016-04-25 14:37:47
【问题描述】:

我正在开发一个 Java Spring+Hibernate 项目,我们有一个 Junit 设置来对我们的代码进行单元测试。 我现在面临的问题是我不明白为什么 Hibernate(使用 Spring-boot)在测试实际运行之前创建数据库模式 2 次。顺序如下:

  1. Alter 表删除所有外键
  2. 删除表(如果存在)
  3. 创建表
  4. 更改表添加约束(如 FK)
  5. Alter 表删除所有外键
  6. 删除表(如果存在)
  7. 创建表
  8. 更改表添加约束
  9. 执行所有测试

我的问题是,如果更具体一点:为什么要执行第 3-6 点? 为什么干脆不执行1,2,7,8,9。我为什么要这个?因为这需要宝贵的时间,我不明白我为什么需要这个。

下面是我的持久化配置:

<persistence-unit name="localContainerEntityForTest">
    <description>Spring JPA LocalContainerEntityManagerFactoryBean</description>
    <provider>org.hibernate.ejb.HibernatePersistence</provider>
    <properties>
        <property name="hibernate.dialect" value="org.hibernate.dialect.MySQLDialect"/>
        <property name="hibernate.hbm2ddl.auto" value="create"/>
        <property name="hibernate.implicit_naming_strategy" value="legacy-jpa"/>
        <property name = "hibernate.show_sql" value = "true" />
        <property name="javax.persistence.jdbc.driver" value="com.mysql.jdbc.Driver"/>
        <property name="javax.persistence.jdbc.url" value="jdbc:mysql://localhost/myApp?createDatabaseIfNotExist=true"/>
        <property name="javax.persistence.jdbc.user" value="hibernate"/>
        <property name="javax.persistence.jdbc.password" value="password"/>
    </properties>
</persistence-unit>

另外,下面是我用于每个单元测试类的注释:

@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(classes = JPAConfigurationTestEnviorement.class)
@WebAppConfiguration
@FixMethodOrder(MethodSorters.NAME_ASCENDING)

【问题讨论】:

    标签: java mysql spring hibernate junit


    【解决方案1】:

    我对 Hibernate 相当熟悉,但对 Spring Boot 不太熟悉。我的猜测是 Hibernate 直接负责一个 create-alter-drop 周期,而 Spring Boot 负责另一个。如果您在道德上反对您当前的设置,那么您可以尝试将您的 Hibernate XML 更新为以下内容:

    <property name="hibernate.hbm2ddl.auto" value="validate"/>
    

    通过选择validate 选项,您将指示 Hibernate 仅验证您现有的模式,而不创建或删除任何表。这里的诀窍是我不确定您要删除两个周期中的哪一个(您也没有告诉我们)。

    【讨论】:

    • 1.我想让junit自己创建数据库,所以create就可以了。 2. Spring boot logo 显示在所有 1-9 步骤之前,所以我想如果你对循环责任的看法是正确的,那么这些是在显示 logo 之后混合的。 3. 我使用 validate 进行实际的应用程序执行(Debug-As,Run-As) 4. 关于要删除的循环,取决于这里的 2,这也是我想知道的区分和排除,如果可能的话。
    • 我现在已经没有子弹了,但我会暂时保留这个答案,以防它激发其他人给你一个完整的答案。
    【解决方案2】:

    发现问题,在启动升级 Spring Boot 版本的过程后,我观察到一些奇怪的代码,之前没有告诉我任何事情。原因是在定义 LocalContainerEntityManagerBean 之前创建了 EntityManagerFactory:

    @Bean
    public LocalContainerEntityManagerFactoryBean getEntityManagerFactoryBean() {
        Persistence.createEntityManagerFactory("localContainerEntityForTest");
    
        LocalContainerEntityManagerFactoryBean lcemfb = new LocalContainerEntityManagerFactoryBean();
        lcemfb.setPersistenceUnitName("localContainerEntityForTest");
        lcemfb.setPackagesToScan("com.mybasepackage");
        lcemfb.setPersistenceXmlLocation("classpath:/META-INF/persistence.xml");
    
        return lcemfb;
    }
    

    删除线后:

    Persistence.createEntityManagerFactory("localContainerEntityForTest");
    

    循环消失了。

    【讨论】:

      猜你喜欢
      • 2010-10-24
      • 2021-05-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-03-02
      • 2014-01-30
      相关资源
      最近更新 更多