Hibernate 4 & # 8594; 5 migration: NamingStrategy changes, no tables found

What i want to do

I am trying to upgrade from WildFly 8.2.0 to WildFly 10.0.0, which means that I have (and want) a transition from Hibernate 4.3 to Hibernate 5.0.

Customization

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 

I have read the migration guide and am amazed at the changes in Naming Strategy . I have read many questions about this on SO, but mine seems a little different. Hibernate complains that no tables were found:

 INFO [ohVersion] HHH000412: Hibernate Core {5.0.7.Final} INFO [ohcfg.Environment] HHH000206: hibernate.properties not found INFO [ohcfg.Environment] HHH000021: Bytecode provider name : javassist INFO [ohannotations.common.Version] HCANN000001: Hibernate Commons Annotations {5.0.1.Final} INFO [ohdialect.Dialect] HHH000400: Using dialect: org.hibernate.dialect.SQLServerDialect INFO [ohenvers.boot.internal.EnversServiceImpl] Envers integration enabled? : true INFO [ohvalidator.internal.util.Version] HV000001: Hibernate Validator 5.2.3.Final INFO [ohtool.hbm2ddl.SchemaValidator] HHH000229: Running schema validator INFO [ohtseiInformationExtractorJdbcDatabaseMetaDataImpl] HHH000262: Table not found: SEC_AUTHORIZATION_RULES INFO [ohtseiInformationExtractorJdbcDatabaseMetaDataImpl] HHH000262: Table not found: SEC_USER More tables not found ... INFO [ohhql.internal.QueryTranslatorFactoryInitiator] (ServerService Thread Pool -- 62) HHH000397: Using ASTQueryTranslatorFactory 

When I switched to registering DEBUG, I saw, for example, that it binds the entity to the correct database table:

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

What is strange to me is that the application works. After this Table not found he does not complain that the scheme is wrong. The application is working. Selects, inserts, updates data.

I have a sleep mode configured through it spring -orm abstraction:

 @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; } 

In this offset object, I name the table names and column names explicitly:

 @Entity @Table(name = "SEC_USER") public class User extends BaseEntity { @Column(name = "LOGIN", nullable = false, unique = true) private String login; 

Questions

  • How to make this table not find log error messages?
  • Why do they appear if table names are explicitly specified?
  • Why doesn't he agree with column names?
  • Why does it seem to be working correctly ?

What i tried

  • Upgrading Spring 4.1.9 to 4.2.5 which says it has Hibernate 5 support
  • Set hibernate.implicit_naming_strategy to legacy-jpa according to this
  • Manually set the default schema and assign the db_owner role. Notice that I never had to do this before sleep mode 4. enter image description here

  • I was debugging hibernation a bit and what I found in InformationExtractorJdbcDatabaseMetaDataImpl.java , which hibernation does not see the directory (whatever it is) and the schema. In the end, I think he should see the diagram. See screenshot below: directory and schema are NULL. enter image description here

+7
java spring hibernate wildfly
source share
5 answers

Solved this using the latest SQL Server JDBC driver. I have been old since 2012. Now I downloaded and used the new JDBC 4.2 from https://www.microsoft.com/en-us/download/details.aspx?id=11774 (sqljdbc_4.2.6420.100_enu.exe → sqljdbc42.jar) and it started working . I could even discard the default schema changes for the SQL user.

0
source share

I figured out the same problem, but with the jtds driver. After some research, I founded that hibernate with SqlServerDialect uses the sp_tables stored procedure to find tables. In this second parameter, SP is the name of the schema, so if it is null , the table search works correctly, and if it is empty, then the line does not.

Sleep mode sets this parameter to null in two cases:

  • if the dialect method getNameQualifierSupport() returns NameQualifierSupport.CATALOG , but all SqlServerDialects return null
  • if the returs driver false in the method 'supports jtds ()', but jtds returns true .

To solve this problem, I decided to extend the SqlServer2012Dialect end override getNameQualifierSupport() method.

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

and set the hibernate.dialect property to the new org.company.SqlServer2012DialectWithCatalogOnly class

Hope this helps ...

+5
source share

As in Hibernate 5, NamingStrategy's logic is divided into two concepts: implicit and physical. You correctly set the implicit naming strategy, but you did not set the physical. Hibernate did not provide a compatible one, so you have to create it yourself:

 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()); } } 

Change this by setting the hibernate.physical_naming_strategy property to the fully qualified class name of the specified class.

0
source share

I think you will be interested to know everything, I recorded the following ticket:

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

Updating the JTDS to the Microsoft JDBC driver will provide a driver that implements Connection.getSchema() , which will obviously solve the problem as reported.

However, if you update this driver and you rely on default_schema to efficiently change the referenced location tables (so that it does not look at the default "dbo" schema for current users, for example) is still out of luck without providing a custom SchemaNameResolver.

The real intrusive part of all this is that implicitSchemaName is never applied during validation.

0
source share

I had a similar problem and solved it this way:

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

0
source share

All Articles