微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

无法将Microsoft SQL Server连接到Spring Boot应用程序

如何解决无法将Microsoft SQL Server连接到Spring Boot应用程序

我正面临这个问题:

我正在使用SpringBoot应用程序,并且有2个数据源,一个MysqL,第二个是Microsoft sql Server

使用JPA

数据库存在于某些远程服务器/机器中。

org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'secondEntityManagerFactory' defined in class path resource [org/my/in/config/SecondDBConfig.class]: Invocation of init method Failed; nested exception is javax.persistence.PersistenceException: [PersistenceUnit: default] Unable to build Hibernate SessionFactory; nested exception is java.lang.classCastException: java.lang.Integer cannot be cast to java.lang.Long
    at org.springframework.beans.factory.support.AbstractAutowireCapablebeanfactory.initializeBean(AbstractAutowireCapablebeanfactory.java:1794) ~[spring-beans-5.2.8.RELEASE.jar:5.2.8.RELEASE]
    at org.springframework.beans.factory.support.AbstractAutowireCapablebeanfactory.doCreateBean(AbstractAutowireCapablebeanfactory.java:594) ~[spring-beans-5.2.8.RELEASE.jar:5.2.8.RELEASE]
    at org.springframework.beans.factory.support.AbstractAutowireCapablebeanfactory.createBean(AbstractAutowireCapablebeanfactory.java:516) ~[spring-beans-5.2.8.RELEASE.jar:5.2.8.RELEASE]
    at org.springframework.beans.factory.support.Abstractbeanfactory.lambda$doGetBean$0(Abstractbeanfactory.java:324) ~[spring-beans-5.2.8.RELEASE.jar:5.2.8.RELEASE]
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:226) ~[spring-beans-5.2.8.RELEASE.jar:5.2.8.RELEASE]
    at org.springframework.beans.factory.support.Abstractbeanfactory.doGetBean(Abstractbeanfactory.java:322) ~[spring-beans-5.2.8.RELEASE.jar:5.2.8.RELEASE]
    at org.springframework.beans.factory.support.Abstractbeanfactory.getBean(Abstractbeanfactory.java:202) ~[spring-beans-5.2.8.RELEASE.jar:5.2.8.RELEASE]
    at org.springframework.context.support.AbstractApplicationContext.getBean(AbstractApplicationContext.java:1109) ~[spring-context-5.2.8.RELEASE.jar:5.2.8.RELEASE]
    at org.springframework.context.support.AbstractApplicationContext.finishbeanfactoryInitialization(AbstractApplicationContext.java:869) ~[spring-context-5.2.8.RELEASE.jar:5.2.8.RELEASE]
    at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:551) ~[spring-context-5.2.8.RELEASE.jar:5.2.8.RELEASE]
    at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:143) ~[spring-boot-2.3.3.RELEASE.jar:2.3.3.RELEASE]
    at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:758) [spring-boot-2.3.3.RELEASE.jar:2.3.3.RELEASE]
    at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:750) [spring-boot-2.3.3.RELEASE.jar:2.3.3.RELEASE]
    at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:397) [spring-boot-2.3.3.RELEASE.jar:2.3.3.RELEASE]
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:315) [spring-boot-2.3.3.RELEASE.jar:2.3.3.RELEASE]
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:1237) [spring-boot-2.3.3.RELEASE.jar:2.3.3.RELEASE]
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:1226) [spring-boot-2.3.3.RELEASE.jar:2.3.3.RELEASE]
    at org.my.in.MyApplication.main(MyApplication.java:10) [classes/:na]
Caused by: javax.persistence.PersistenceException: [PersistenceUnit: default] Unable to build Hibernate SessionFactory; nested exception is java.lang.classCastException: java.lang.Integer cannot be cast to java.lang.Long
    at org.springframework.orm.jpa.AbstractEntityManagerfactorybean.buildNativeEntityManagerFactory(AbstractEntityManagerfactorybean.java:403) ~[spring-orm-5.2.8.RELEASE.jar:5.2.8.RELEASE]
    at org.springframework.orm.jpa.AbstractEntityManagerfactorybean.afterPropertiesSet(AbstractEntityManagerfactorybean.java:378) ~[spring-orm-5.2.8.RELEASE.jar:5.2.8.RELEASE]
    at org.springframework.orm.jpa.LocalContainerEntityManagerfactorybean.afterPropertiesSet(LocalContainerEntityManagerfactorybean.java:341) ~[spring-orm-5.2.8.RELEASE.jar:5.2.8.RELEASE]
    at org.springframework.beans.factory.support.AbstractAutowireCapablebeanfactory.invokeInitMethods(AbstractAutowireCapablebeanfactory.java:1853) ~[spring-beans-5.2.8.RELEASE.jar:5.2.8.RELEASE]
    at org.springframework.beans.factory.support.AbstractAutowireCapablebeanfactory.initializeBean(AbstractAutowireCapablebeanfactory.java:1790) ~[spring-beans-5.2.8.RELEASE.jar:5.2.8.RELEASE]
    ... 17 common frames omitted
Caused by: java.lang.classCastException: java.lang.Integer cannot be cast to java.lang.Long
    at com.microsoft.sqlserver.jdbc.sqlServerResultSet.getLong(sqlServerResultSet.java:2151) ~[mssql-jdbc-6.4.0.jre8.jar:na]
    at com.zaxxer.hikari.pool.HikariProxyResultSet.getLong(HikariProxyResultSet.java) ~[HikariCP-3.4.5.jar:na]
    at org.hibernate.tool.schema.extract.internal.SequenceinformationExtractorLegacyImpl.resultSetStartValueSize(SequenceinformationExtractorLegacyImpl.java:129) ~[hibernate-core-5.4.20.Final.jar:5.4.20.Final]
    at org.hibernate.tool.schema.extract.internal.SequenceinformationExtractorLegacyImpl.extractMetadata(SequenceinformationExtractorLegacyImpl.java:59) ~[hibernate-core-5.4.20.Final.jar:5.4.20.Final]
    at org.hibernate.tool.schema.extract.internal.DatabaseinformationImpl.initializeSequences(DatabaseinformationImpl.java:65) ~[hibernate-core-5.4.20.Final.jar:5.4.20.Final]
    at org.hibernate.tool.schema.extract.internal.DatabaseinformationImpl.<init>(DatabaseinformationImpl.java:59) ~[hibernate-core-5.4.20.Final.jar:5.4.20.Final]
    at org.hibernate.tool.schema.internal.Helper.buildDatabaseinformation(Helper.java:155) ~[hibernate-core-5.4.20.Final.jar:5.4.20.Final]
    at org.hibernate.tool.schema.internal.AbstractSchemaMigrator.doMigration(AbstractSchemaMigrator.java:96) ~[hibernate-core-5.4.20.Final.jar:5.4.20.Final]
    at org.hibernate.tool.schema.spi.SchemaManagementToolCoordinator.performDatabaseAction(SchemaManagementToolCoordinator.java:184) ~[hibernate-core-5.4.20.Final.jar:5.4.20.Final]
    at org.hibernate.tool.schema.spi.SchemaManagementToolCoordinator.process(SchemaManagementToolCoordinator.java:73) ~[hibernate-core-5.4.20.Final.jar:5.4.20.Final]
    at org.hibernate.internal.SessionFactoryImpl.<init>(SessionFactoryImpl.java:316) ~[hibernate-core-5.4.20.Final.jar:5.4.20.Final]
    at org.hibernate.boot.internal.SessionFactoryBuilderImpl.build(SessionFactoryBuilderImpl.java:469) ~[hibernate-core-5.4.20.Final.jar:5.4.20.Final]
    at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.build(EntityManagerFactoryBuilderImpl.java:1259) ~[hibernate-core-5.4.20.Final.jar:5.4.20.Final]
    at org.springframework.orm.jpa.vendor.SpringHibernateJpaPersistenceProvider.createContainerEntityManagerFactory(SpringHibernateJpaPersistenceProvider.java:58) ~[spring-orm-5.2.8.RELEASE.jar:5.2.8.RELEASE]
    at org.springframework.orm.jpa.LocalContainerEntityManagerfactorybean.createNativeEntityManagerFactory(LocalContainerEntityManagerfactorybean.java:365) ~[spring-orm-5.2.8.RELEASE.jar:5.2.8.RELEASE]
    at org.springframework.orm.jpa.AbstractEntityManagerfactorybean.buildNativeEntityManagerFactory(AbstractEntityManagerfactorybean.java:391) ~[spring-orm-5.2.8.RELEASE.jar:5.2.8.RELEASE]
    ... 21 common frames omitted


解决方法

这是known bug in hubernate

他们找到的解决方案是创建一个自定义方言(非常奇怪...)

package ....;

import org.hibernate.dialect.SQLServer2012Dialect;
import org.hibernate.tool.schema.extract.internal.SequenceInformationExtractorNoOpImpl;
import org.hibernate.tool.schema.extract.spi.SequenceInformationExtractor;
/**
 * Custom SQLServer dialect to deal with SEQUENCE schema query result processing issue
 */
public class SQLServerCustomDialect extends SQLServer2012Dialect {

  @Override
  public SequenceInformationExtractor getSequenceInformationExtractor() {
    if ( getQuerySequencesString() == null ) {
      return SequenceInformationExtractorNoOpImpl.INSTANCE;
    }
    else {
      return SequenceInformationExtractorImpl.INSTANCE;
    }
  }

}

使用稍微笨拙的适配器类可以在int和long之间正确转换值

/*
 * Hibernate,Relational Persistence for Idiomatic Java
 *
 * License: GNU Lesser General Public License (LGPL),version 2.1 or later.
 * See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
 *
 * Adapted from the class with the same name in the Hibernate distribution.
 */

package ...;

import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.List;

import org.hibernate.boot.model.relational.QualifiedSequenceName;
import org.hibernate.engine.jdbc.env.spi.IdentifierHelper;
import org.hibernate.tool.schema.extract.internal.SequenceInformationExtractorNoOpImpl;
import org.hibernate.tool.schema.extract.internal.SequenceInformationImpl;
import org.hibernate.tool.schema.extract.spi.ExtractionContext;
import org.hibernate.tool.schema.extract.spi.SequenceInformation;
import org.hibernate.tool.schema.extract.spi.SequenceInformationExtractor;

/**
 * @author Steve Ebersole
 */
public class SequenceInformationExtractorImpl implements SequenceInformationExtractor {
  /**
   * Singleton access
   */
  public static final SequenceInformationExtractorImpl INSTANCE = new SequenceInformationExtractorImpl();

  @Override
  public Iterable<SequenceInformation> extractMetadata(final ExtractionContext extractionContext) throws SQLException {
    final String lookupSql = extractionContext.getJdbcEnvironment().getDialect().getQuerySequencesString();

    // *should* never happen,but to be safe in the interest of performance...
    if ( lookupSql == null ) {
      return SequenceInformationExtractorNoOpImpl.INSTANCE.extractMetadata( extractionContext );
    }

    final IdentifierHelper identifierHelper = extractionContext.getJdbcEnvironment().getIdentifierHelper();
    final Statement statement = extractionContext.getJdbcConnection().createStatement();
    try {
      final ResultSet resultSet = statement.executeQuery( lookupSql );
      try {
        final List<SequenceInformation> sequenceInformationList = new ArrayList<>();
        while ( resultSet.next() ) {
          sequenceInformationList.add(
              new SequenceInformationImpl(
                  new QualifiedSequenceName(
                      identifierHelper.toIdentifier(
                        resultSetCatalogName( resultSet )
                      ),identifierHelper.toIdentifier(
                          resultSetSchemaName( resultSet )
                      ),identifierHelper.toIdentifier(
                          resultSetSequenceName( resultSet )
                      )
                  ),resultSetStartValueSize( resultSet ),resultSetMinValue( resultSet ),resultSetMaxValue( resultSet ),resultSetIncrementValue( resultSet )
              )
          );
        }
        return sequenceInformationList;
      }
      finally {
        try {
          resultSet.close();
        }
        catch (final SQLException ignore) {
        }
      }
    }
    finally {
      try {
        statement.close();
      }
      catch (final SQLException ignore) {
      }
    }
  }

  protected String sequenceNameColumn() {
    return "sequence_name";
  }

  protected String sequenceCatalogColumn() {
    return "sequence_catalog";
  }

  protected String sequenceSchemaColumn() {
    return "sequence_schema";
  }

  protected String sequenceStartValueColumn() {
    return "start_value";
  }

  protected String sequenceMinValueColumn() {
    return "minimum_value";
  }

  protected String sequenceMaxValueColumn() {
    return "maximum_value";
  }

  protected String sequenceIncrementColumn() {
    return "increment";
  }

  protected String resultSetSequenceName(final ResultSet resultSet) throws SQLException {
    return resultSet.getString( sequenceNameColumn() );
  }

  protected String resultSetCatalogName(final ResultSet resultSet) throws SQLException {
    final String column = sequenceCatalogColumn();
    return column != null ? resultSet.getString( column ) : null;
  }

  protected String resultSetSchemaName(final ResultSet resultSet) throws SQLException {
    final String column = sequenceSchemaColumn();
    return column != null ? resultSet.getString( column ) : null;
  }

  protected Long resultSetStartValueSize(final ResultSet resultSet) throws SQLException {
    final String column = sequenceStartValueColumn();
    return column != null ? resultSetGetAsLong( resultSet,column ) : null;
  }

  protected Long resultSetMinValue(final ResultSet resultSet) throws SQLException {
    final String column = sequenceMinValueColumn();
    return column != null ? resultSetGetAsLong( resultSet,column ) : null;
  }

  protected Long resultSetMaxValue(final ResultSet resultSet) throws SQLException {
    final String column = sequenceMaxValueColumn();
    return column != null ? resultSetGetAsLong( resultSet,column ) : null;
  }

  protected Long resultSetIncrementValue(final ResultSet resultSet) throws SQLException {
    final String column = sequenceIncrementColumn();
    return column != null ? resultSetGetAsLong( resultSet,column ) : null;
  }

  private Long resultSetGetAsLong(final ResultSet resultSet,final String column) throws SQLException {
    final Object value = resultSet.getObject(column);
    if (value == null || !(value instanceof Number)) {
      return null;
    }
    return ((Number)value).longValue();
  }
}

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。