jHipster, MS SQL, and Liquibase throwing java.lang.NoSuchMethodError

I am trying to adapt jHipster so that it uses MS SQL, I am along the way writting a small guide as to how to do so, since I couldn’t find one online, but I’ve seen other people mention they did port it, so I know it’s possible at least.

What I’ve done so far is add some dependencies to pom.xml:

pom.xml

[...]
<!-- Microsoft JDBC -->
<dependency>
    <groupId>com.microsoft.sqlserver</groupId>
    <artifactId>sqljdbc41</artifactId>
    <version>4.1</version>
</dependency>
<!-- Liquibase MS SQL Server extensions -->
<dependency>
    <groupId>org.liquibase.ext</groupId>
    <artifactId>liquibase-mssql</artifactId>
    <version>1.2.0</version>
</dependency>
[...]

Change application-dev.yml settings so that they are using MS SQL:

application-dev.yml

spring:
    profiles:
        active: dev
    datasource:
        dataSourceClassName: com.microsoft.sqlserver.jdbc.SQLServerDataSource
        url: jdbc:sqlserver://localhost:1433;databaseName=test
        databaseName: test
        serverName:
        username: root
        password: supersecretpassword
        cachePrepStmts: true
        prepStmtCacheSize: 250
        prepStmtCacheSqlLimit: 2048
        useServerPrepStmts: true
    jpa:
        database-platform: org.hibernate.dialect.SQLServerDialect
        database: SQLServer
        openInView: false
        show_sql: true
        generate-ddl: false
        hibernate:
            ddl-auto: none
            naming-strategy: org.hibernate.cfg.EJB3NamingStrategy
        properties:
            hibernate.cache.use_second_level_cache: true
            hibernate.cache.use_query_cache: false
            hibernate.generate_statistics: true
            hibernate.cache.region.factory_class: org.hibernate.cache.ehcache.SingletonEhCacheRegionFactory

Go into the 00000000000000_initial_schema.xml file to make some changes so that it will properly run on MS SQL (Such as Insert ON for the default users):

<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.1.xsd
    http://www.liquibase.org/xml/ns/dbchangelog-ext http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-ext.xsd">

    <property name="now" value="GETDATE()" dbms="mssql"/>
    <property name="now" value="current_timestamp" dbms="mssql"/>

    <changeSet id="00000000000000" author="jhipster" dbms="mssql">
        <createSequence sequenceName="hibernate_sequence" startValue="1000" incrementBy="1"/>
    </changeSet>

    [...]

    <ext:loadData encoding="UTF-8"
              file="config/liquibase/authorities.csv"
              separator=";"
              tableName="JHI_AUTHORITY"
              identityInsertEnabled="true" />

    <ext:loadData encoding="UTF-8"
              file="config/liquibase/users_authorities.csv"
              separator=";"
              tableName="JHI_USER_AUTHORITY"
              identityInsertEnabled="true" />

And at this point when trying to run the application I’m getting a Liquibase error:

Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'liquibase' defined in class path resource [com/winserver/config/DatabaseConfiguration.class]: Invocation of init method failed; nested exception is java.lang.NoSuchMethodError: liquibase.database.Database.escapeTableName(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;

and

Caused by: java.lang.NoSuchMethodError: liquibase.database.Database.escapeTableName(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;

Now my DatabaseConfiguration.java file is 100% default currently. I am certain I must have to modify something there, but I cannot tell what needs to be changed.

DatabaseConfiguration.java

@Configuration
@EnableJpaRepositories("com.winserver.repository")
@EnableJpaAuditing(auditorAwareRef = "springSecurityAuditorAware")
@EnableTransactionManagement
public class DatabaseConfiguration implements EnvironmentAware {

    private final Logger log = LoggerFactory.getLogger(DatabaseConfiguration.class);

    private RelaxedPropertyResolver propertyResolver;

    private Environment env;

    @Autowired(required = false)
    private MetricRegistry metricRegistry;

    @Override
    public void setEnvironment(Environment env) {
        this.env = env;
        this.propertyResolver = new RelaxedPropertyResolver(env, "spring.datasource.");
    }

    @Bean(destroyMethod = "shutdown")
    @ConditionalOnMissingClass(name = "com.winserver.config.HerokuDatabaseConfiguration")
    @Profile("!" + Constants.SPRING_PROFILE_CLOUD)
    public DataSource dataSource() {
        log.debug("Configuring Datasource");
        if (propertyResolver.getProperty("url") == null && propertyResolver.getProperty("databaseName") == null) {
            log.error("Your database connection pool configuration is incorrect! The application" +
                    " cannot start. Please check your Spring profile, current profiles are: {}",
                    Arrays.toString(env.getActiveProfiles()));

            throw new ApplicationContextException("Database connection pool is not configured correctly");
        }
        HikariConfig config = new HikariConfig();
        config.setDataSourceClassName(propertyResolver.getProperty("dataSourceClassName"));
        if(StringUtils.isEmpty(propertyResolver.getProperty("url"))) {
            config.addDataSourceProperty("databaseName", propertyResolver.getProperty("databaseName"));
            config.addDataSourceProperty("serverName", propertyResolver.getProperty("serverName"));
        } else {
            config.addDataSourceProperty("url", propertyResolver.getProperty("url"));
        }
        config.addDataSourceProperty("user", propertyResolver.getProperty("username"));
        config.addDataSourceProperty("password", propertyResolver.getProperty("password"));

        //MySQL optimizations, see https://github.com/brettwooldridge/HikariCP/wiki/MySQL-Configuration
        if ("com.mysql.jdbc.jdbc2.optional.MysqlDataSource".equals(propertyResolver.getProperty("dataSourceClassName"))) {
            config.addDataSourceProperty("cachePrepStmts", propertyResolver.getProperty("cachePrepStmts", "true"));
            config.addDataSourceProperty("prepStmtCacheSize", propertyResolver.getProperty("prepStmtCacheSize", "250"));
            config.addDataSourceProperty("prepStmtCacheSqlLimit", propertyResolver.getProperty("prepStmtCacheSqlLimit", "2048"));
        }
        if (metricRegistry != null) {
            config.setMetricRegistry(metricRegistry);
        }
        return new HikariDataSource(config);
    }

    @Bean
    public SpringLiquibase liquibase(DataSource dataSource) {
        SpringLiquibase liquibase = new SpringLiquibase();
        liquibase.setDataSource(dataSource);
        liquibase.setChangeLog("classpath:config/liquibase/master.xml");
        liquibase.setContexts("development, production");
        if (env.acceptsProfiles(Constants.SPRING_PROFILE_FAST)) {
            if ("org.h2.jdbcx.JdbcDataSource".equals(propertyResolver.getProperty("dataSourceClassName"))) {
                liquibase.setShouldRun(true);
                log.warn("Using '{}' profile with H2 database in memory is not optimal, you should consider switching to" +
                    " MySQL or Postgresql to avoid rebuilding your database upon each start.", Constants.SPRING_PROFILE_FAST);
            } else {
                liquibase.setShouldRun(false);
            }
        } else {
            log.debug("Configuring Liquibase");
        }
        return liquibase;
    }

    @Bean
    public Hibernate4Module hibernate4Module() {
        return new Hibernate4Module();
    }
}

Can anyone point me in the right direction? Have a great weekend.


Source: java

Leave a Reply