Reputation: 2141
I'm creating a jhipster based project and I'm having some problems in integration tests. I've removed login column from t_user table and did some changes to use e-mail as login. The liquibase migration works fine in MySQL, however I'm getting this error when I'm running some tests:
java.lang.IllegalStateException: Failed to load ApplicationContext
at org.springframework.test.context.DefaultCacheAwareContextLoaderDelegate.loadContext(DefaultCacheAwareContextLoaderDelegate.java:94)
at org.springframework.test.context.DefaultTestContext.getApplicationContext(DefaultTestContext.java:72)
at org.springframework.test.context.support.DependencyInjectionTestExecutionListener.injectDependencies(DependencyInjectionTestExecutionListener.java:117)
at org.springframework.test.context.support.DependencyInjectionTestExecutionListener.prepareTestInstance(DependencyInjectionTestExecutionListener.java:83)
at org.springframework.test.context.TestContextManager.prepareTestInstance(TestContextManager.java:212)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.createTest(SpringJUnit4ClassRunner.java:200)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner$1.runReflectiveCall(SpringJUnit4ClassRunner.java:252)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.methodBlock(SpringJUnit4ClassRunner.java:254)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:217)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:83)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61)
at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:68)
at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:163)
at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:77)
at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:195)
at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:63)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:120)
Caused by: org.springframework.context.ApplicationContextException: Unable to start embedded container; nested exception is java.lang.RuntimeException: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'org.springframework.security.config.annotation.web.configuration.WebSecurityConfiguration': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire method: public void org.springframework.security.config.annotation.web.configuration.WebSecurityConfiguration.setFilterChainProxySecurityConfigurer(org.springframework.security.config.annotation.ObjectPostProcessor,java.util.List) throws java.lang.Exception; nested exception is org.springframework.beans.factory.BeanExpressionException: Expression parsing failed; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'securityConfiguration': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private org.springframework.security.core.userdetails.UserDetailsService com.brevleq.consami.config.SecurityConfiguration.userDetailsService; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'userDetailsService': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private com.brevleq.consami.repository.UserRepository com.brevleq.consami.security.UserDetailsService.userRepository; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'userRepository': Cannot create inner bean '(inner bean)#1f481ec3' of type [org.springframework.orm.jpa.SharedEntityManagerCreator] while setting bean property 'entityManager'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name '(inner bean)#1f481ec3': Cannot resolve reference to bean 'entityManagerFactory' while setting constructor argument; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'liquibase' defined in class path resource [com/brevleq/consami/config/DatabaseConfiguration.class]: Invocation of init method failed; nested exception is liquibase.exception.MigrationFailedException: Migration failed for change set classpath:config/liquibase/changelog/20150328154659_changelog.xml::1427568441617-1::hudson (generated):
Reason: liquibase.exception.DatabaseException: org.h2.jdbc.JdbcSQLException: Constraint "IDX_USER_LOGIN" not found; SQL statement:
ALTER TABLE PUBLIC.t_user DROP CONSTRAINT idx_user_login [90057-183]
at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.onRefresh(EmbeddedWebApplicationContext.java:133)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:474)
at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.refresh(EmbeddedWebApplicationContext.java:118)
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:691)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:321)
at org.springframework.boot.test.SpringApplicationContextLoader.loadContext(SpringApplicationContextLoader.java:98)
at org.springframework.test.context.DefaultCacheAwareContextLoaderDelegate.loadContextInternal(DefaultCacheAwareContextLoaderDelegate.java:68)
at org.springframework.test.context.DefaultCacheAwareContextLoaderDelegate.loadContext(DefaultCacheAwareContextLoaderDelegate.java:86)
... 28 more
As you can see, the error is that it can't find 'idx_user_login' so, it stops the test in the database migration. The specified migration file is this:
<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog" xmlns:ext="http://www.liquibase.org/xml/ns/dbchangelog-ext" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog-ext http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-ext.xsd http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.3.xsd">
<changeSet author="hudson (generated)" id="1427568441617-1">
<dropUniqueConstraint constraintName="idx_user_login" tableName="t_user"/>
</changeSet>
<changeSet author="hudson (generated)" id="1427568441617-2">
<dropUniqueConstraint constraintName="login" tableName="t_user"/>
</changeSet>
<changeSet author="hudson (generated)" id="1427568441617-3">
<dropColumn columnName="login" tableName="t_user"/>
</changeSet>
<changeSet author="hudson (generated)" id="1427568441617-4">
<addNotNullConstraint columnDataType="varchar(50)" columnName="email" tableName="T_USER"/>
</changeSet>
</databaseChangeLog>
As I told, this migration is running correctly in MySQL. This file was generated using
mvn compile liquibase:diff
Is there something I can do to make this migration work in my tests?
Upvotes: 2
Views: 8532
Reputation: 11
I had the same issue working with mysql for production and H2 for test Solved it by disabling liquibase for tests, and enabling schema creation by hibernate. In test/resources/application.properties
spring.datasource.url = jdbc:h2:mem:test;MODE=Mysql
spring.jpa.properties.hibernate.dialect = org.hibernate.dialect.H2Dialect
spring.jpa.hibernate.ddl-auto=create #Replace validate !Here!
#Liquibase
spring.liquibase.enabled=false #Replace true by false !Here!
Upvotes: 1
Reputation: 653
I had just the same issue but it turns out H2 is only being used as a test DB for some tests that do require a Spring Context to be configured (such tests are run with "test" profile enabled). The solution in our case was to simply deleting the data.*
files (the data files for H2) given they were in a inconsistent state with the incoming changes.
If your case is for local dev database, then losing your data is no big issue and this solution may work for you.
Upvotes: 0
Reputation: 1460
I had the same problem: removing a unique contstraint in PostgreSQL was working fine, bun when I ran the integration tests against a H2 database, it complained not finding the constraint I wanted to drop.
I figured out that, when creating the constraint, no specific constraintName
was configured.
Apparently PostgreSQL and H2 do not generated the same constraint name. This is why it worked in only one of them.
My solution was to fix the previous script, where the constraint was created, by adding a specific name.
<column name="report_id" type="bigint">
<constraints unique="true" uniqueConstraintName="visit_report_id_key"/>
</column>
This way, there is no difference between PostgreSQL and H2
Upvotes: 2
Reputation: 1081
Here is my solution, how to run liquibase before the text execution on H2:
Simply copy the src/main/resources/liquibase/master.xml
to src/test/resources/liquibase/master.xml
.
After you have made a copy of the master.xml under src/test, liquibase would magically also run before tests and apply all changesets. Because the H2 test database is normally not persistet, liquibase would spread its changesets everytime on a clean database.
However you have to copy the master.xml everytime you create changesets. I have found no way (till now) how to setup JHipster to automatically apply changesets to the test database.
Upvotes: 3