2016-02-26 51 views
4

我需要迁移我的JPA /休眠(5.1)从MySQL的Java EE应用程序到SQL Server(2012)。由于JPA提供的抽象,我谦卑的想法是这个简单而直接。如何将Hibernate从MySQL迁移到SQL Server?

我开始装上Wildfly 10的SQL服务器JDBC驱动程序4.2,从微软网站下载,并确定导致成功的连接测试新的数据源。

然后,我再版我的应用程序,让休眠重建数据库表,但我卡在此:

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

我也尝试添加此,因为我的SQL Server 2012上,但什么都没有改变:

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

任何想法或建议?

更新

问题似乎只与hibernate.hbm2ddl.auto = update发生,因为有create它的工作原理。但我真的需要update工作像它与MySQL一样,因为我是沉重的发展和我的架构变化频繁。

回答

4

SQL Server需要明确的目录架构设置。

在持久性附加描述。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" /> 

裁判:

+0

hibernate.default_catalog = [数据库名称]修复它,谢谢! – BrunoJCM

+1

这是我的pov中的一个错误。它在4.3中工作得很好。现在,Hibernate不会向SQL Server发出正确的查询,如果在@Table中只指定模式并且没有目录!我提出了一个错误https://hibernate.atlassian.net/browse/HHH-10978 –

0

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

检查你的实体不使用任何作为表名或列名。

+0

他们没有,这都是JPA的默认设置。我没有'@ Table'和'@ Column's,但是我发现这个问题只有'update' DDL,'create'有效。 –

+0

您是否尝试切换到再次更新?您在上面写道,只有在出现问题后才设置方言,可能会引入某种不可恢复的架构不匹配。 – newohybat

0

我不得不使用Hibernate 5.1.0.Final与SQL Server 2012类似的问题我降级冬眠4.3.11.Final和解决的问题。

休眠的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 

希望这有助于!

1

问题上升当您使用@Table与模式值,但没有产品目录值和无休眠.default_catalog在persistence.xml中指定。

这是我的pov中的一个bug。它在4.3中工作得很好。现在,Hibernate不会向SQL Server发出正确的查询,如果在@Table中只指定模式并且没有目录!我在这里提出了一个错误:https://hibernate.atlassian.net/browse/HHH-10978

0

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

该线程已经非常有帮助和Spring引导1.5.9.RELEASE它使用Hibernate 5.0.12.Final

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

所以,如果你使用Spring启动与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。