当我使用liquibase更改模型数据时,JHipster集成测试失败

时间:2017-09-15 10:39:39

标签: spring postgresql h2 jhipster liquibase

总结:我更新了我的课程,测试课程和我的数据库,以便通过电子邮件登录。我写了一个liquibase的更改日志来进行数据库的更改。 运行该项目,一切正常,但如果我执行集成测试,liquibase的更改日志工作正常。

我认为它正在发生:

  1. 我尝试执行测试。
  2. 使用每个更改日志(初始和海关)初始化H2数据库
  3. 测试开始执行。
  4. 在每次测试之前,H2数据库不会被删除,但会调用更改日志(或仅调用我的自定义更改日志)。
  5. 我的自定义更改日志失败,因为它无法找到在第2点删除的登录列,而且它没有"已恢复"通过初始 更改日志。
  6. 完整版:我用4.8.0生成了一个JHipster应用程序。我的.yo-rc.json:

    {
      "generator-jhipster": {
        "promptValues": {
          "packageName": "com.company.name",
          "nativeLanguage": "es"
        },
        "jhipsterVersion": "4.8.0",
        "baseName": "name",
        "packageName": "com.company.name",
        "packageFolder": "com/company/name",
        "serverPort": "8080",
        "authenticationType": "jwt",
        "hibernateCache": "no",
        "clusteredHttpSession": false,
        "websocket": false,
        "databaseType": "sql",
        "devDatabaseType": "postgresql",
        "prodDatabaseType": "postgresql",
        "searchEngine": false,
        "messageBroker": false,
        "serviceDiscoveryType": false,
        "buildTool": "gradle",
        "enableSocialSignIn": false,
        "enableSwaggerCodegen": false,
        "jwtSecretKey": "secret",
        "clientFramework": "angularX",
        "useSass": true,
        "clientPackageManager": "yarn",
        "applicationType": "monolith",
        "testFrameworks": [],
        "jhiPrefix": "jhi",
        "enableTranslation": true,
        "nativeLanguage": "es",
        "languages": [
          "es"
        ]
      }
    }
    

    我想从JHI_USER中删除登录列并从JHI_USER的电子邮件中删除唯一约束并使其不为null,然后,我将所有代码更改为我需要的(我删除了每个对登录的引用,我将它们更改为电子邮件)和编码三个liquibase changelog的文件:

    a)20170913130000_drop_login_column_JhiUser.xml:

    <?xml version="1.0" encoding="UTF-8" ?>
    <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 http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.5.xsd
                            http://www.liquibase.org/xml/ns/dbchangelog-ext http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-ext.xsd">
        <changeSet id="20170913130000" author="svalero">
            <dropColumn columnName="login" tableName="jhi_user" />
        </changeSet>
    </databaseChangeLog>
    

    B)20170913180000_drop_unique_constraint_email_JhiUser.xml:

    <?xml version="1.0" encoding="UTF-8" ?>
    <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 http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.5.xsd
                            http://www.liquibase.org/xml/ns/dbchangelog-ext http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-ext.xsd">
        <changeSet id="20170913180000" author="svalero">
            <dropUniqueConstraint constraintName="jhi_user_email_key"
                tableName="jhi_user" />
        </changeSet>
    </databaseChangeLog>
    

    C)20170913182100_add_notnull_constraint_email_JhiUser.xml

    <?xml version="1.0" encoding="UTF-8" ?>
    <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 http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.5.xsd
                            http://www.liquibase.org/xml/ns/dbchangelog-ext http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-ext.xsd">
        <changeSet id="20170913182100" author="svalero">
            <addNotNullConstraint columnDataType="varchar(100)"
                columnName="email"
                tableName="jhi_user"/>
        </changeSet>
    </databaseChangeLog>
    

    我还在master.xml上添加了它们,一切都在应用程序上完美运行(./gradlew和yarn start)。

    但是,当我尝试执行集成测试(./gradlew测试)时,我在每次测试时都得到了这个:

    com.company.name.web.rest.AuditResourceIntTest > getNonExistingAudit FAILED
        java.lang.IllegalStateException
            Caused by: org.springframework.beans.factory.BeanCreationException
                Caused by: liquibase.exception.MigrationFailedException
                    Caused by: liquibase.exception.DatabaseException
                        Caused by: org.h2.jdbc.JdbcSQLException
    

    从测试结果我发现了这个:

    Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'liquibase' defined in class path resource [com/company/name/config/DatabaseConfiguration.class]: Invocation of init method failed; nested exception is liquibase.exception.MigrationFailedException: Migration failed for change set config/liquibase/changelog/20170913180000_drop_unique_constraint_email_JhiUser.xml::20170913180000::svalero:
         Reason: liquibase.exception.DatabaseException: Constraint &quot;JHI_USER_EMAIL_KEY&quot; not found; 
         SQL statement: ALTER TABLE PUBLIC.jhi_user DROP CONSTRAINT jhi_user_email_key [90057-196] [Failed SQL: ALTER TABLE PUBLIC.jhi_user DROP CONSTRAINT jhi_user_email_key]
    

    然后,我认为在每次测试时我的自定义更改日志都被调用,但初始更改日志未被调用,因为我的更改日志无法找到初始更改日志必须创建的列或约束。

    我的第一个&#34; walkaround&#34;很简单,添加前提条件来更改日志,如:

    <preConditions onFail="MARK_RAN" onError="MARK_RAN">
        <columnExists columnName="login" tableName="jhi_user" schemaName="public" />
    </preConditions>
    

    但是Liquibase没有先决条件来解决&#34;独特约束&#34;我发现这是为了检查&#34; jhi_user_email_key&#34;约束存在:

    <preConditions onFail="MARK_RAN" onError="MARK_RAN">
        <sqlCheck expectedResult="1">select count (*) from pg_constraint where conname='jhi_user_email_key'</sqlCheck>
    </preConditions>
    

    但是在H2(JHipster使用这种数据库进行测试)我们没有pg_constraint,这不起作用。

    最后,出了什么问题?为什么测试只运行我的更改日志而忽略了初始更改日志?我该如何解决?

2 个答案:

答案 0 :(得分:0)

同时我在JHipster上创建了一个PR 6460,它被合并了,我想它已经成为下一个版本4.9.1的一部分了。唯一约束的名称为 ux_user_mail ,即您的文件 B)20170913180000_drop_unique_constraint_email_JhiUser.xml 应更改为:

..... <dropUniqueConstraint constraintName="ux_user_mail" tableName="jhi_user" /> .....

但是,删除LOGIN列会对登录过程产生影响,即您需要更改 UserService 类的方法 getUserWithAuthorities ,例如。

@Transactional(readOnly = true)
public User getUserWithAuthorities() {
    return userRepository.findOneWithAuthoritiesByEmail(SecurityUtils.getCurrentUserLogin()).orElse(null);
}
DomainUserDetailsS​​ervice类中的

loadUserByUsername

 @Override
@Transactional
public UserDetails loadUserByUsername(final String login) {
    log.debug("Authenticating {}", login);
    String lowercaseLogin = login.toLowerCase(Locale.ENGLISH);
    Optional<User> userFromDatabase = userRepository.findOneWithAuthoritiesByEmail(lowercaseLogin);
    return ........

UserRepository 也需要使用搜索方法进行丰富,例如

@EntityGraph(attributePaths = "authorities")
Optional<User> findOneWithAuthoritiesByEmail(String email);

另一方面,您还需要删除域类User的登录属性。仅删除 @Column 注释是不够的。即使属性 login 在没有 @Column 注释的类中,hibernate也不会使用SchemaManagementException,因为JHipster命名策略是这样配置的

jpa:
    hibernate:
        naming:
            physical-strategy: org.springframework.boot.orm.jpa.hibernate.SpringPhysicalNamingStrategy
            implicit-strategy: org.springframework.boot.orm.jpa.hibernate.SpringImplicitNamingStrategy

并且希望列登录存在于 jhi_user 表中。可以找到命名策略的文档here

对于您的第二个liquibase changeSet * 20170913180000_drop_unique_constraint_email_JhiUser.xml *我建议您验证是否存在约束 jhi_user_email_key

这将使您可以使用电子邮件进行登录。仍然通过从域类用户中删除 login 属性,你需要重构生产中的一些类以及测试代码

答案 1 :(得分:0)

在JHipster 4.10.0或更高版本上,感谢@duderoot,它是这样创建的:

        <column name="email" type="varchar(100)">
            <constraints unique="true" nullable="true" uniqueConstraintName="ux_user_email"/>
        </column>       

然后,您可以使用此名称删除此约束,而不会出现任何问题。

在JHipster 4.8.0上,创建了一个“唯一约束”:

        <column name="email" type="varchar(100)">
            <constraints unique="true" nullable="true"/>
        </column>

它们不使用“uniqueConstraintName”,并且约束的名称在每个数据库上都不同。

在Postgresql(dev配置文件)上,“jhi_user_email_key”存在但在H2(测试配置文件)中它不存在。

要解决此问题,您可以在Initial Schema上添加uniqueConstraintName:

        <column name="email" type="varchar(100)">
            <constraints unique="true" nullable="true" uniqueConstraintName="jhi_user_email_key"/>
        </column>

或者使用“dbms”前置条件创建不同的更改日志。