2016-03-10 8 views
7

Quello che voglio fare

sto cercando di migrare da wildfly 8.2.0 a wildfly 10.0.0 il che significa che ho (e voglio) migrare da Hibernate 4.3 a Hibernate 5.0.Hibernate 4 -> 5 migrazione: modifiche NamingStrategy, Tavoli non trovato

Setup

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 

Ho letto l'migration guide e io sono colpito dalla Naming strategia modifiche. I havereadmanyquestions su questo su SO, ma il mio sembra un po 'diverso. Hibernate si lamenta che le tabelle non si trovano:

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 

quando sono passato a registrazione di debug ho visto per esempio che egli è vincolante l'entità alla corretta tabella di DB:

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} 

Qual è strano per me è che l'app funzioni. Dopo questo Table not found s non si lamenta che lo schema non sia corretto. L'app funziona. Selezionare, inserire, aggiornare i dati funziona.

ho Hibernate configurato attraverso la sua primavera-orm astrazione:

@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 questa entità correspoding ho i nomi delle tabelle e delle colonne di nome in modo esplicito:

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

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

Domande

  • Come rendere questa tabella non trovata I messaggi di log scompaiono?
  • Perché vengono visualizzati se i nomi delle tabelle sono esplicitamente denominati?
  • Perché non si lamenta dei nomi delle colonne?
  • Perché è apparentemente funzionante corretto?

quello che ho cercato

  • Aggiornamento primavera 4.1.9 a 4.2.5 che says he has support for Hibernate 5
  • Impostare hibernate.implicit_naming_strategy a legacy-APP secondo le this
  • Set manualmente lo schema predefinito e assegnato il ruolo db_owner. Nota non ho mai avuto a che fare prima con Hibernate 4. enter image description here

  • ho debug hibernate un po 'e quello che ho trovato nel InformationExtractorJdbcDatabaseMetaDataImpl.java che vanno in letargo non vede il catalogo (qualunque cosa questo è) e schema. A pensarci penso che dovrebbe vedere lo schema. Vedi screenshot qui sotto: il catalogo e lo schema sono nulli. enter image description here

risposta

0

Risolto questo utilizzando il più recente driver JDBC di SQL Server. A ha avuto uno vecchio dal 2012. Ora ho scaricato e utilizzato il più recente JDBC 4.2 da https://www.microsoft.com/en-us/download/details.aspx?id=11774 (sqljdbc_4.2.6420.100_enu.exe -> sqljdbc42.jar) e ha iniziato a funzionare. Potrei anche ripristinare le modifiche dello schema di default per l'utente SQL.

+0

Hmm. Non ha davvero senso. Sei sicuro di non aver provato più cose allo stesso tempo? La versione del driver SQL non dovrebbe avere nulla a che fare con questo. –

+0

Sì, davvero. Ho ripristinato tutte le mie modifiche relative allo schema e lasciato solo il set 'hibernate.implicit_naming_strategy' e poi ho cambiato il driver JDBC avanti e indietro e basta. Forse http://stackoverflow.com/users/1025118/vlad-mihalcea vedrà questo thread e commenterà :) –

0

Come di Hibernate 5, la logica del NamingStrategy è divisa in due concetti: impliciti e fisiche. Hai impostato correttamente la strategia di denominazione implicita, ma non hai impostato quella fisica. Hibernate non ha fornito uno compatibile, quindi bisogna creare uno voi stessi:

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

} 

Cambio di utilizzare questo impostando la hibernate.physical_naming_strategy struttura al nome di classe completo della classe di cui sopra.

+0

Ho verificato questo, ma non è questo. Nel mio caso sembra che fosse il driver JDBC. –

5

Stavo capendo lo stesso problema, ma con il driver jtds. Dopo alcune ricerche, ho fondato, che ibernato con SqlServerDialect utilizza la stored procedure sp_tables per trovare la dichiarazione delle tabelle. In quel secondo parametro SP è il nome dello schema, quindi, se la ricerca della tabella è null e se è vuota stringa - non.

Hibernate imposta questo parametro su null in due casi:

  • se il metodo dialetto getNameQualifierSupport() ritorna NameQualifierSupport.CATALOG, ma tutti i SqlServerDialects tornare null
  • se returs conducente false in 'supportsSchemasInTableDefinitions()' metodo, ma jtds restituisce true.

Per risolvere questo problema, ho deciso di estendere il metodo override getNameQualifierSupport().

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

e impostare la proprietà hibernate.dialect alla nuova classe org.company.SqlServer2012DialectWithCatalogOnly

Spero che questo aiuti ...

0

Penso che sarete tutti interessati a conoscere, ho registrato il seguente biglietto:

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

L'aggiornamento da JTDS al microsoft JDBC driver fornisce un driver che implementa Connection.getSchema() che, ovviamente, risolverà il problema, come riportato,.

Tuttavia, se si aggiorna a tale driver e si fa affidamento su default_schema per modificare in modo efficace le tabelle di posizione a cui fa riferimento (in modo che non guardi lo schema predefinito 'dbo' degli utenti correnti, ad esempio) si Sarò ancora sfortunato, senza fornire uno SchemaNameResolver personalizzato.

Il vero pezzo fastidioso di tutto questo è che l'implicito NomeSchema non viene mai applicato durante la convalida.

0

ho avuto problema simile e ho risolto in questo modo:

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

Problemi correlati