2016-03-10 29 views
7

我想要做的

我试图从迁移8.2.0 WildFly到WildFly 10.0.0这意味着我有(和希望)什么从Hibernate 4.3迁移到Hibernate 5.0。休眠4 - > 5迁移:NamingStrategy变化,表中未发现

设置

Java 8u40 
Spring 4.1.9 
SQL Server 2012 
Wildfly 8.2.0 -> Wildfly 10.0.0 
Hibernate 4.3.6 -> Hibernate 5.0.7 

我已阅读migration guide和我被打命名策略变化。我have​​manyquestions关于这个SO,但我的看起来有点不同。 Hibernate的抱怨表找不到:

INFO [o.h.Version] HHH000412: Hibernate Core {5.0.7.Final} 
INFO [o.h.cfg.Environment] HHH000206: hibernate.properties not found 
INFO [o.h.cfg.Environment] HHH000021: Bytecode provider name : javassist 
INFO [o.h.annotations.common.Version] HCANN000001: Hibernate Commons Annotations {5.0.1.Final} 
INFO [o.h.dialect.Dialect] HHH000400: Using dialect: org.hibernate.dialect.SQLServerDialect 
INFO [o.h.envers.boot.internal.EnversServiceImpl] Envers integration enabled? : true 
INFO [o.h.validator.internal.util.Version] HV000001: Hibernate Validator 5.2.3.Final 
INFO [o.h.tool.hbm2ddl.SchemaValidator] HHH000229: Running schema validator 
INFO [o.h.t.s.e.i.InformationExtractorJdbcDatabaseMetaDataImpl] HHH000262: Table not found: SEC_AUTHORIZATION_RULES 
INFO [o.h.t.s.e.i.InformationExtractorJdbcDatabaseMetaDataImpl] HHH000262: Table not found: SEC_USER 
More tables not found ... 
INFO [o.h.hql.internal.QueryTranslatorFactoryInitiator] (ServerService Thread Pool -- 62) HHH000397: Using ASTQueryTranslatorFactory 

当我切换到调试日志记录我看到的例子,他是实体结合到正确的数据库表:

DEBUG [o.h.c.a.EntityBinder] Bind entity com.company.user.User on table SEC_USER 
DEBUG [o.h.c.Ejb3Column] Binding column: Ejb3Column{table=org.hibernate.mapping.Table(SEC_USER), mappingColumn=ID, insertable=true, updatable=true, unique=false} 

什么是奇怪我是该应用程序的作品。在此Table not found之后,它并不抱怨模式不正确。该应用程序工作。选择,插入,更新数据的作品。

我已经休眠通过它配置的spring-ORM抽象:

@Bean(name = "myEmf") 
@DependsOn({"dataSource", "flyway"}) 
public LocalContainerEntityManagerFactoryBean entityManagerFactoryBean() { 
    LocalContainerEntityManagerFactoryBean em = new LocalContainerEntityManagerFactoryBean(); 
    em.setDataSource(dataSource()); 
    em.setPackagesToScan(new String[]{"com.company.**.*"}); 
    em.setJpaVendorAdapter(new HibernateJpaVendorAdapter()); 
    em.setJpaProperties(additionalProperties()); 
    return em; 
} 

private Properties additionalProperties() { 
    Properties propFile = propertiesFile(); 
    properties.setProperty("hibernate.hbm2ddl.auto", "validate"); 
    properties.setProperty("hibernate.dialect", "org.hibernate.dialect.SQLServer2012Dialect"); 
    properties.setProperty("hibernate.show_sql", "false"); 
    properties.setProperty("hibernate.format_sql", "true"); 
    properties.setProperty("hibernate.id.new_generator_mappings", "false"); 
    properties.setProperty("hibernate.use_sql_comments", "false"); 
    properties.setProperty("hibernate.implicit_naming_strategy", "legacy-jpa"); 
    return properties; 
} 

在这种correspoding实体我已经表名和列名明确命名:

@Entity 
@Table(name = "SEC_USER") 
public class User extends BaseEntity { 

    @Column(name = "LOGIN", nullable = false, unique = true) 
    private String login; 

问题

  • 如何使这张表找不到日志消息?
  • 为什么他们出现,如果我有表名显式命名?
  • 他为什么不抱怨列名?
  • 他为什么看似正常工作

我曾尝试

  • 升级4.1.9春季4.2.5到其says he has support for Hibernate 5
  • 设置hibernate.implicit_naming_strategy根据this
  • 设置传统,JPA手动设置默认模式并分配角色db_owner。注意我从来没有与Hibernate 4 enter image description here

  • 我已经调试冬眠了一下,我在冬眠不看目录(无论这是)和架构的InformationExtractorJdbcDatabaseMetaDataImpl.java发现之前做到这一点。在我看来,他应该看到架构。请参阅下面的截图:目录和模式为空。 enter image description here

回答

0

通过使用最新的SQL Server JDBC驱动程序来解决此问题。 A有一个从2012年的老。现在我下载并使用最新的JDBC 4.2从https://www.microsoft.com/en-us/download/details.aspx?id=11774(sqljdbc_4.2.6420.100_enu.exe - > sqljdbc42.jar),它开始工作。我甚至可以恢复SQL用户的默认模式更改。

+0

嗯。这真的没有意义。你确定你没有在同一时间尝试多件事吗? SQL驱动程序版本与此无关。 –

+0

是的,真的。我恢复了关于模式的所有更改,只留下了'hibernate.implicit_naming_strategy'集,然后来回切换JDBC驱动程序,就是这样。也许http://stackoverflow.com/users/1025118/vlad-mihalcea会看到这个线程和评论:) –

0

作为休眠5,NamingStrategy的逻辑被分裂成两个概念:隐式和物理层。您已经正确设置了隐式命名策略,但您尚未设置物理命名策略。休眠没有提供一个兼容的,所以你必须自己创建一个:

public class LegacyPhysicalNamingStrategy implements PhysicalNamingStrategy { 
    private final Pattern pattern = Pattern.compile("(\\p{Lower}+)(\\p{Upper}+)"); 
    public Identifier toPhysicalCatalogName(Identifier name, JdbcEnvironment jdbcEnvironment) { 
     return convert(name); 
    } 

    public Identifier toPhysicalSequenceName(Identifier name, JdbcEnvironment jdbcEnvironmen) { 
     return convert(name); 
    } 

    public Identifier toPhysicalColumnName(Identifier name, JdbcEnvironment jdbcEnvironmen) { 
     return convert(name); 
    } 

    public Identifier toPhysicalTableName(Identifier name, JdbcEnvironment jdbcEnvironmen) { 
     return convert(name); 
    } 

    public Identifier toPhysicalSchemaName(Identifier name, JdbcEnvironment jdbcEnvironmen) { 
     return convert(name); 
    } 

    private Identifier convert(Identifier identifier) { 
     if (identifier == null || identifier.getText().trim().isEmpty()) { 
      return identifier; 
     } 

     String text = identifier.getText(); 
     text = pattern.matcher(text).replaceAll("$1_$2").toLowerCase(); 
     return Identifier.toIdentifier(text, identifier.isQuoted()); 
    } 

} 

更改为使用该酒店所hibernate.physical_naming_strategy为上述类的完全限定类名。

+0

我已经验证了这一点,但是这不是它。在我的情况下,它似乎是JDBC驱动程序。 –

5

我正在计算出相同的问题,但使用jtds驱动程序。经过一番研究,我创建了这个冬眠用SqlServerDialect使用sp_tables存储过程来查找表的声明。在该SP第二个参数是模式名称,所以,如果它是null表搜索正确工作,并且它是否为空字符串 - 不是。

休眠设置此参数null在两种情况下:

  • 如果getNameQualifierSupport()返回NameQualifierSupport.CATALOG,但所有SqlServerDialects返回null
  • 方言方法,如果司机returs false在 'supportsSchemasInTableDefinitions()' 方法,但jtds回报true

为了解决这个问题,我决定扩展SqlServer2012Dialect结束覆盖getNameQualifierSupport()方法。

public class SqlServer2012DialectWithCatalogOnly extends SQLServer2012Dialect { 
    @Override 
    public NameQualifierSupport getNameQualifierSupport() { 
     return NameQualifierSupport.CATALOG; 
    } 
} 

,并设置属性hibernate.dialect新类org.company.SqlServer2012DialectWithCatalogOnly

希望这有助于...

0

我想你都会有兴趣知道,我已经记录了以下门票:

https://hibernate.atlassian.net/browse/HHH-11424

将JTDS更新到Microsoft JDBC驱动程序将为您提供一个驱动程序,该驱动程序实现了Connection.getSchema()其中,显然,解决问题,如报道。但是,如果您更新到该驱动程序,并且您依赖default_schema来有效更改位置表(例如,它不会查看当前用户默认的'dbo'架构),那么您如果没有提供自定义的SchemaNameResolver,它仍然会运气不佳。

所有这一切的真正麻烦之处在于implicitSchemaName从未在验证过程中应用。

0

我有类似的问题,我用这种方式解决:

jpaProperties.put("hibernate.hbm2ddl.jdbc_metadata_extraction_strategy", "individually")