2015-11-04 9 views
5

Ho un problema con l'inserimento di entità che utilizzano sequenze in un database MSSQL 2014. Uso Hibernate fornito con Wildfly 10 CR4 (ma in CR1 e CR2 ho avuto lo stesso problema).Dialetto di ibernazione errato per MSSQL 2014

Ecco un'informazioni generali sull'ambiente corsa webapp:

  1. wildfly 10 (CR4)
  2. Java 8 u 51
  3. Windows 7 Proffesional 64bit
  4. MSSQL Server 2014
  5. MSSQL driver: sqljdbc42.jar è distribuito sul server delle applicazioni

Il mio file persistence.xml si presenta così:

<persistence-unit name="mb_managed_pu" transaction-type="JTA"> 
    <provider>org.hibernate.jpa.HibernatePersistenceProvider</provider> 
    <jta-data-source>java:/jdbc/datasource</jta-data-source> 
    <properties> 
     <property name="hibernate.archive.autodetection" value="class, hbm" /> 
     <property name="hibernate.show_sql" value="true" /> 
     <property name="hibernate.format_sql" value="true" /> 
     <property name="hibernate.jdbc.batch_size" value="0" /> 
     <property name="hibernate.default_schema_" value="openmap"/> 
     <property name="hibernate.connection.useUnicode" value="yes"/> 
     <property name="hibernate.connection.characterEncoding" value="UTF-8"/> 
    </properties> 
</persistence-unit> 

Ora qui è quello che succede quando mi imbatto in un errore.

In primo luogo, quando viene avviato wildfly, posso vedere questo avvertimento:

WARN [org.hibernate.engine.jdbc.dialect.internal.StandardDialectResolver] (ServerService pool di thread - 68) HHH000385: Unknown Microsoft Versione principale di SQL Server [12] utilizzando il dialetto SQL Server 2000

Ho controllato il web e ho scoperto che questo problema è già noto da gennaio 2015, ma sfortunatamente è ancora an open issue.

L'errore si è sollevata quando provo a persistere una nuova entità che ha l'ID configurato per utilizzare le sequenze:

@Id 
@Column(name = "MAP_BOOKMARK_ID") 
@SequenceGenerator(name = "SEQ_MAP_BOOKMARKS", sequenceName = "SEQ_MAP_BOOKMARKS", allocationSize = 1) 
@GeneratedValue(generator = "SEQ_MAP_BOOKMARKS", strategy = GenerationType.SEQUENCE) 
private long     id; 

L'eccezione sollevata è la seguente:

com.microsoft.sqlserver .jdbc.SQLServerException: nome oggetto non valido "SEQ_MAP_BOOKMARKS".

Questa non è una sorpresa poiché l'ibernazione usa il dialetto sbagliato, quello che non sa nulla delle sequenze.

Quando modifico persistence.xml e aggiungi questa linea:

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

tutto funziona come un fascino.

Il problema è che l'applicazione funzionerà anche con il database Oracle su un altro server e su Postgres su un altro. Mi piacerebbe evitare di dover preparare più versioni della stessa applicazione.

Qualcuno sa di una soluzione a questo problema? O dovrei aspettare che venga visualizzata un'altra versione di Wildfly e/o di ibernazione?

+2

estrarre il valore "" org.hibernate.dialect.SQLServer2012Dialect "" in un file di proprietà. Metti questo file nella cartella conf del tomcat. Utilizzare i segnaposti di primavera per impostare il dialetto. Con questa configurazione è possibile distribuire la guerra sui due server diversi e si deve solo modificare il file delle proprietà nel tomcat. –

risposta

3

nel frattempo la squadra non risolve questo problema, è possibile creare un sistema di risoluzione dialetto personalizzato:

public class ScopeStandardDialectResolver implements DialectResolver { 


private static final long serialVersionUID = 1L; 

    @Override 
    public Dialect resolveDialect(DialectResolutionInfo info) { 
     Dialect customDialectResolver = customDialectResolver(info); 
     Log.getInstance().logInfo(Thread.currentThread().getStackTrace(), customDialectResolver.getClass().getName()); 
     return customDialectResolver; 
    } 

    private Dialect customDialectResolver(DialectResolutionInfo info) { 
     final String databaseName = info.getDatabaseName(); 
     final int majorVersion = info.getDatabaseMajorVersion(); 
     if (isSqlServer2014(databaseName, majorVersion)) { 
      return new SQLServer2012Dialect(); 
     } else { 
      return StandardDialectResolver.INSTANCE.resolveDialect(info); 
     } 
    } 

    private boolean isSqlServer2014(final String databaseName, final int majorVersion) { 
     return databaseName.startsWith("Microsoft SQL Server") && majorVersion == 12; 
    } 

} 

Poi si configura nella vostra unità di persistenza:

<property name="hibernate.dialect_resolvers" value="com.oki.scope.hibernate.ScopeStandardDialectResolver" /> 

relativo a questo esempio: http://blog.exxeta.com/2016/03/23/dynamically-resolve-hibernate-database-dialect/

2

Penso che il problema potrebbe essere correlato a questo noto problema HHH-9570.(Il collegamento contiene effettivamente la mia richiesta pull per la soluzione proposta)

Fondamentalmente, come è successo prima con SQL Server 2012, lo StandardDialectResolver di Hibernate non riconosce SQL Server 2014 ([Major versione 12]) e quindi il dialetto predefinito SQLServerDialect viene restituito, che è quello per SQL Server 2000

-5

In realtà questo problema viene a causa di una corretta mappatura non di tabelle. Controlla le tabelle e le mappature delle classi di entità.

1

Per Springboot 1.4.7 e inferiori aggiungere qui sotto per file delle proprietà

spring.jpa.properties.hibernate.dialect =org.hibernate.dialect.SQLServer2012Dialect