【问题标题】:How to migrate Hibernate from MySQL to SQL Server?如何将 Hibernate 从 MySQL 迁移到 SQL Server?
【发布时间】:2016-06-09 16:26:33
【问题描述】:

我需要将我的 JPA/Hibernate (5.1) Java EE 应用程序从 MySQL 迁移到 SQL Server (2012)。由于 JPA 提供了抽象,我的拙见是认为这要简单明了。

我开始在 Wildfly 10 上加载 SQL Server JDBC 4.2 驱动程序,从 Microsoft 网站下载,并定义新的数据源,从而成功进行连接测试。

然后,我重新发布了我的应用程序,让 Hibernate 重建数据库表,但我被困在这个问题上:

13:27:29,268 WARN  [org.hibernate.engine.jdbc.spi.SqlExceptionHelper] (ServerService Thread Pool -- 61) SQL Error: 1038, SQLState: S0004
13:27:29,268 ERROR [org.hibernate.engine.jdbc.spi.SqlExceptionHelper] (ServerService Thread Pool -- 61) An object or column name is missing or empty. For SELECT INTO statements, verify each column has a name. For other statements, look for empty alias names. Aliases defined as "" or [] are not allowed. Change the alias to a valid name.
13:27:29,270 ERROR [org.jboss.msc.service.fail] (ServerService Thread Pool -- 61) MSC000001: Failed to start service jboss.persistenceunit."best.war#best": org.jboss.msc.service.StartException in service jboss.persistenceunit."best.war#best": javax.persistence.PersistenceException: [PersistenceUnit: best] Unable to build Hibernate SessionFactory
    at org.jboss.as.jpa.service.PersistenceUnitServiceImpl$1$1.run(PersistenceUnitServiceImpl.java:172)
    at org.jboss.as.jpa.service.PersistenceUnitServiceImpl$1$1.run(PersistenceUnitServiceImpl.java:117)
    at org.wildfly.security.manager.WildFlySecurityManager.doChecked(WildFlySecurityManager.java:667)
    at org.jboss.as.jpa.service.PersistenceUnitServiceImpl$1.run(PersistenceUnitServiceImpl.java:182)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
    at java.lang.Thread.run(Thread.java:745)
    at org.jboss.threads.JBossThread.run(JBossThread.java:320)
Caused by: javax.persistence.PersistenceException: [PersistenceUnit: best] Unable to build Hibernate SessionFactory
    at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.persistenceException(EntityManagerFactoryBuilderImpl.java:954)
    at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.build(EntityManagerFactoryBuilderImpl.java:884)
    at org.jboss.as.jpa.hibernate5.TwoPhaseBootstrapImpl.build(TwoPhaseBootstrapImpl.java:44)
    at org.jboss.as.jpa.service.PersistenceUnitServiceImpl$1$1.run(PersistenceUnitServiceImpl.java:154)
    ... 7 more
Caused by: org.hibernate.exception.SQLGrammarException: Error accessing table metadata
    at org.hibernate.exception.internal.SQLStateConversionDelegate.convert(SQLStateConversionDelegate.java:106)
    at org.hibernate.exception.internal.StandardSQLExceptionConverter.convert(StandardSQLExceptionConverter.java:42)
    at org.hibernate.engine.jdbc.spi.SqlExceptionHelper.convert(SqlExceptionHelper.java:111)
    at org.hibernate.engine.jdbc.spi.SqlExceptionHelper.convert(SqlExceptionHelper.java:97)
    at org.hibernate.tool.schema.extract.internal.InformationExtractorJdbcDatabaseMetaDataImpl.convertSQLException(InformationExtractorJdbcDatabaseMetaDataImpl.java:99)
    at org.hibernate.tool.schema.extract.internal.InformationExtractorJdbcDatabaseMetaDataImpl.locateTableInNamespace(InformationExtractorJdbcDatabaseMetaDataImpl.java:354)
    at org.hibernate.tool.schema.extract.internal.InformationExtractorJdbcDatabaseMetaDataImpl.getTable(InformationExtractorJdbcDatabaseMetaDataImpl.java:228)
    at org.hibernate.tool.schema.internal.exec.ImprovedDatabaseInformationImpl.getTableInformation(ImprovedDatabaseInformationImpl.java:109)
    at org.hibernate.tool.schema.internal.SchemaMigratorImpl.performMigration(SchemaMigratorImpl.java:252)
    at org.hibernate.tool.schema.internal.SchemaMigratorImpl.doMigration(SchemaMigratorImpl.java:137)
    at org.hibernate.tool.schema.internal.SchemaMigratorImpl.doMigration(SchemaMigratorImpl.java:110)
    at org.hibernate.tool.schema.spi.SchemaManagementToolCoordinator.performDatabaseAction(SchemaManagementToolCoordinator.java:176)
    at org.hibernate.tool.schema.spi.SchemaManagementToolCoordinator.process(SchemaManagementToolCoordinator.java:64)
    at org.hibernate.internal.SessionFactoryImpl.<init>(SessionFactoryImpl.java:458)
    at org.hibernate.boot.internal.SessionFactoryBuilderImpl.build(SessionFactoryBuilderImpl.java:465)
    at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.build(EntityManagerFactoryBuilderImpl.java:881)
    ... 9 more
Caused by: com.microsoft.sqlserver.jdbc.SQLServerException: An object or column name is missing or empty. For SELECT INTO statements, verify each column has a name. For other statements, look for empty alias names. Aliases defined as "" or [] are not allowed. Change the alias to a valid name.
    at com.microsoft.sqlserver.jdbc.SQLServerException.makeFromDatabaseError(SQLServerException.java:217)
    at com.microsoft.sqlserver.jdbc.TDSTokenHandler.onEOF(tdsparser.java:251)
    at com.microsoft.sqlserver.jdbc.TDSParser.parse(tdsparser.java:81)
    at com.microsoft.sqlserver.jdbc.TDSParser.parse(tdsparser.java:36)
    at com.microsoft.sqlserver.jdbc.SQLServerConnection$1ConnectionCommand.doExecute(SQLServerConnection.java:1834)
    at com.microsoft.sqlserver.jdbc.TDSCommand.execute(IOBuffer.java:6276)
    at com.microsoft.sqlserver.jdbc.SQLServerConnection.executeCommand(SQLServerConnection.java:1793)
    at com.microsoft.sqlserver.jdbc.SQLServerConnection.connectionCommand(SQLServerConnection.java:1839)
    at com.microsoft.sqlserver.jdbc.SQLServerConnection.setCatalog(SQLServerConnection.java:2190)
    at com.microsoft.sqlserver.jdbc.SQLServerDatabaseMetaData.switchCatalogs(SQLServerDatabaseMetaData.java:331)
    at com.microsoft.sqlserver.jdbc.SQLServerDatabaseMetaData.getResultSetFromStoredProc(SQLServerDatabaseMetaData.java:282)
    at com.microsoft.sqlserver.jdbc.SQLServerDatabaseMetaData.getResultSetWithProvidedColumnNames(SQLServerDatabaseMetaData.java:309)
    at com.microsoft.sqlserver.jdbc.SQLServerDatabaseMetaData.getTables(SQLServerDatabaseMetaData.java:496)
    at org.hibernate.tool.schema.extract.internal.InformationExtractorJdbcDatabaseMetaDataImpl.locateTableInNamespace(InformationExtractorJdbcDatabaseMetaDataImpl.java:339)
    ... 19 more

13:27:29,278 ERROR [org.jboss.as.controller.management-operation] (Controller Boot Thread) WFLYCTL0013: Operation ("deploy") failed - address: ([("deployment" => "best.war")]) - failure description: {"WFLYCTL0080: Failed services" => {"jboss.persistenceunit.\"best.war#best\"" => "org.jboss.msc.service.StartException in service jboss.persistenceunit.\"best.war#best\": javax.persistence.PersistenceException: [PersistenceUnit: best] Unable to build Hibernate SessionFactory
    Caused by: javax.persistence.PersistenceException: [PersistenceUnit: best] Unable to build Hibernate SessionFactory
    Caused by: org.hibernate.exception.SQLGrammarException: Error accessing table metadata
    Caused by: com.microsoft.sqlserver.jdbc.SQLServerException: An object or column name is missing or empty. For SELECT INTO statements, verify each column has a name. For other statements, look for empty alias names. Aliases defined as \"\" or [] are not allowed. Change the alias to a valid name."}}
13:27:29,300 INFO  [org.jboss.as.server] (ServerService Thread Pool -- 34) WFLYSRV0010: Deployed "best.war" (runtime-name : "best.war")
13:27:29,301 INFO  [org.jboss.as.controller] (Controller Boot Thread) WFLYCTL0183: Service status report
WFLYCTL0186:   Services which failed to start:      service jboss.persistenceunit."best.war#best": org.jboss.msc.service.StartException in service jboss.persistenceunit."best.war#best": javax.persistence.PersistenceException: [PersistenceUnit: best] Unable to build Hibernate SessionFactory

发生了什么事?这是我的persistence.xml:

<persistence version="2.1" xmlns="http://xmlns.jcp.org/xml/ns/persistence"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence http://xmlns.jcp.org/xml/ns/persistence/persistence_2_1.xsd">
    <persistence-unit name="best" transaction-type="JTA">
        <jta-data-source>java:/datasource/mssql/best</jta-data-source>
        <properties>
            <property name="hibernate.hbm2ddl.auto" value="update" />
        </properties>
    </persistence-unit>
  </persistence-units>
</persistence>

我也尝试添加这个,因为我使用的是 SQL Server 2012,但没有任何改变:

<property name="hibernate.dialect" value="org.hibernate.dialect.SQLServer2012Dialect" />

有什么想法或建议吗?

更新

问题似乎只发生在hibernate.hbm2ddl.auto = update 上,因为create 可以工作。但我真的需要update 来像使用 MySQL 一样工作,因为我正在进行大量开发并且我的架构经常更改。

【问题讨论】:

    标签: java sql-server hibernate jpa wildfly


    【解决方案1】:

    SQL Server 需要明确的 catalog 和 schema 设置。

    persistence.xml 中的附加说明:

    <property name="hibernate.dialect" value="org.hibernate.dialect.SQLServer2012Dialect" />
    <property name="hibernate.default_catalog" value="[database name]" />
    <property name="hibernate.default_schema" value="dbo" />
    <property name="hibernate.id.new_generator_mappings" value="false" />
    

    参考:

    【讨论】:

    • hibernate.default_catalog=[数据库名称] 已修复,谢谢!!
    • 这是我的观点中的一个错误。它在 4.3 中运行良好。现在,如果在 @Table 中仅指定了模式而没有目录,Hibernate 不会向 SQL Server 发出正确的查询!我提出了一个错误hibernate.atlassian.net/browse/HHH-10978
    • 谢谢!对于那些努力设置与 mssql 对话的 Quarkus 应用程序的人:``` quarkus.hibernate-orm.dialect=org.hibernate.dialect.SQLServer2012Dialect quarkus.hibernate-orm.database.default-catalog=DBNAME quarkus.hibernate-orm。 database.default-schema=SCHEMANAME ```
    【解决方案2】:

    当您使用带有架构值但没有目录值且没有在 persistence.xml 中指定 hibernate.default_catalog 的 @Table 时,问题就出现了。

    这是我的观点中的一个错误。它在 4.3 中运行良好。现在,如果在 @Table 中仅指定了模式而没有目录,Hibernate 不会向 SQL Server 发出正确的查询!我在这里提出了一个错误:https://hibernate.atlassian.net/browse/HHH-10978

    【讨论】:

      【解决方案3】:

      MySQL 和 SQL Server 都有一些特定的关键字或保留名称。

      检查您的实体没有使用任何作为表名或列名。

      【讨论】:

      • 他们没有,这都是 JPA 的默认设置。我没有@Tables 也没有@Columns,但我发现问题只出在update DDL,create 有效。
      • 您是否尝试再次切换到更新?您在上面写道,您只是在出现问题后才设置方言,可能是引入了某种不可恢复的模式不匹配。
      【解决方案4】:

      我在 SQL Server 2012 中使用休眠 5.1.0.Final 时遇到了类似的问题。我降级到休眠 4.3.11.Final 并解决了这个问题。 p>

      休眠 EntityManager 5.1.0.Final

      INFO  Version:37 - HHH000412: Hibernate Core {5.1.0.Final}
      INFO  Environment:213 - HHH000206: hibernate.properties not found
      INFO  Environment:317 - HHH000021: Bytecode provider name : javassist
      INFO  Version:66 - HCANN000001: Hibernate Commons Annotations {5.0.1.Final}
      INFO  Dialect:156 - HHH000400: Using dialect: org.hibernate.dialect.SQLServer2012Dialect
      INFO  Version:30 - HV000001: Hibernate Validator 5.2.4.Final
      WARN  SqlExceptionHelper:129 - SQL Error: 1038, SQLState: S0004
      ERROR SqlExceptionHelper:131 - Falta o está vacío un nombre de objeto o columna. Compruebe si todas las columnas de las instrucciones SELECT INTO tienen un nombre. Para otras instrucciones, busque si hay nombres de alias vacíos. No se permiten los alias definidos como "" o []. Cambie el alias por un nombre válido.
      

      休眠 EntityManager 4.3.11.Final

      Version:54 - HHH000412: Hibernate Core {4.3.11.Final}
      Environment:239 - HHH000206: hibernate.properties not found
      Environment:346 - HHH000021: Bytecode provider name : javassist
      Version:66 - HCANN000001: Hibernate Commons Annotations {4.0.5.Final}
      Dialect:145 - HHH000400: Using dialect: org.hibernate.dialect.SQLServer2012Dialect
      ASTQueryTranslatorFactory:47 - HHH000397: Using ASTQueryTranslatorFactory
      Version:30 - HV000001: Hibernate Validator 5.2.4.Final
      SchemaValidator:157 - HHH000229: Running schema validator
      SchemaValidator:165 - HHH000102: Fetching database metadata
      TableMetadata:65 - HHH000261: Table found: rino.rino.tipo_ticket
      

      希望这会有所帮助!

      【讨论】:

        【解决方案5】:

        我在这里的这个线程迟到了,但是当我无法让 Spring Boot JPA 与 MS SQL Server 一起使用它与 MySQL 和 Postgres 的工作方式时,我来到了这里。

        此线程对使用 Hibernate 5.0.12.Final 的 Spring Boot 1.5.9.RELEASE 非常有帮助。

        另请注意,许多教程都显示了 Spring Boot application.propeties 文件,其中包含数据库和休眠的条目,这些条目现在已被 Spring Boot 取代为更新的属性。

        因此,如果您将 Spring Boot 与 Microsoft SQL Server 一起使用,请使用以下样式的属性

        spring.datasource.url=jdbc:sqlserver://127.0.0.1:1433;jdbc.databaseName=mydb
        spring.datasource.username=admin
        spring.datasource.password=aadmin
        spring.datasource.driver-class-name=com.microsoft.sqlserver.jdbc.SQLServerDriver
        spring.jpa.database=sql-server
        spring.jpa.show-sql=true
        spring.jpa.hibernate.ddl-auto=update
        

        在您的实体中,您需要提供以下架构信息:

        import javax.persistence.Entity;
        import javax.persistence.GeneratedValue;
        import javax.persistence.GenerationType;
        import javax.persistence.Id;
        import javax.persistence.Table;
        
        @Entity
        @Table(schema="dbo", name="MyUser",catalog="mydatabase")
        public class MyUser {
            @Id
            @GeneratedValue(strategy = GenerationType.AUTO)
            private Integer id;
            private String name;
            private int age;
        
            public MyUser() {
            }
        
            public MyUser(String name, int age) {
                this.name = name;
                this.age = age;
            }
        
            public Integer getId() {
                return id;
            }
        
            public void setId(Integer id) {
                this.id = id;
            }
        
            public String getName() {
                return name;
            }
        
            public void setName(String name) {
                this.name = name;
            }
        
            public int getAge() {
                return age;
            }
        
            public void setAge(int age) {
                this.age = age;
            }
        
            @Override
            public String toString() {
                return "User{" + ", name='" + name + '\'' + ", Age=" + age + '}';
            }
        }
        

        注意:@Table 注释的catalog 属性应该是您的数据库名称。上面提到的Spring Boot和Hibernate结合使用时,连接和访问Microsoft SQL Server需要它。

        【讨论】:

          猜你喜欢
          • 2016-08-12
          • 1970-01-01
          • 2011-06-17
          • 2014-05-24
          • 2012-05-14
          • 2010-09-18
          • 2011-06-23
          • 1970-01-01
          • 2011-03-31
          相关资源
          最近更新 更多