XMight XMight - 2 months ago 23
Java Question

Junit Hibernate creates database schema multiple times

I'm working on a Java Spring+Hibernate project and we have a Junit setup in order to unit-test our code.
The problem I face right now is that I don't understand why Hibernate (with Spring-boot) creates the database schema 2 times before the tests actually run. The sequence is as follows:


  1. Alter tables drop all foreign keys

  2. Drop tables if exist

  3. Create tables

  4. Alter tables add constraints (like FK)

  5. Alter tables drop all foreign keys

  6. Drop tables if exist

  7. Create tables

  8. Alter tables add constraints

  9. Execute all tests



My questions is, if to be more specific: Why points 3-6 including are executed?
Why simply not to execute 1,2,7,8,9. Why do I want this? Because it takes precious time and I don't understand why do I need this.

Below is my persistence configuration:

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


Also, below are the annotations I use for every unit test class:

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

Answer

Problem found, after starting the process to upgrade the spring boot version and I observed some weird code that was not telling me anything before. The reason was the creation of EntityManagerFactory before defining the LocalContainerEntityManagerBean:

@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;
}

After removing the line:

Persistence.createEntityManagerFactory("localContainerEntityForTest");

the cycle disappeared.

Comments