org.hibernate.HibernateException: l'accesso a DialectResolutionInfo non può essere nullo quando 'hibernate.dialect' non è impostato


205

Sto provando a eseguire un'applicazione di avvio a molla che utilizza l'ibernazione tramite spring-jpa, ma sto ottenendo questo errore:

Caused by: org.hibernate.HibernateException: Access to DialectResolutionInfo cannot be null when 'hibernate.dialect' not set
        at org.hibernate.engine.jdbc.dialect.internal.DialectFactoryImpl.determineDialect(DialectFactoryImpl.java:104)
        at org.hibernate.engine.jdbc.dialect.internal.DialectFactoryImpl.buildDialect(DialectFactoryImpl.java:71)
        at org.hibernate.engine.jdbc.internal.JdbcServicesImpl.configure(JdbcServicesImpl.java:205)
        at org.hibernate.boot.registry.internal.StandardServiceRegistryImpl.configureService(StandardServiceRegistryImpl.java:111)
        at org.hibernate.service.internal.AbstractServiceRegistryImpl.initializeService(AbstractServiceRegistryImpl.java:234)
        at org.hibernate.service.internal.AbstractServiceRegistryImpl.getService(AbstractServiceRegistryImpl.java:206)
        at org.hibernate.cfg.Configuration.buildTypeRegistrations(Configuration.java:1885)
        at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:1843)
        at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl$4.perform(EntityManagerFactoryBuilderImpl.java:850)
        at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl$4.perform(EntityManagerFactoryBuilderImpl.java:843)
        at org.hibernate.boot.registry.classloading.internal.ClassLoaderServiceImpl.withTccl(ClassLoaderServiceImpl.java:398)
        at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.build(EntityManagerFactoryBuilderImpl.java:842)
        at org.hibernate.jpa.HibernatePersistenceProvider.createContainerEntityManagerFactory(HibernatePersistenceProvider.java:152)
        at org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean.createNativeEntityManagerFactory(LocalContainerEntityManagerFactoryBean.java:336)
        at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.afterPropertiesSet(AbstractEntityManagerFactoryBean.java:318)
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1613)
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1550)
        ... 21 more

il mio file pom.xml è questo:

<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>1.1.8.RELEASE</version>
</parent>

<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-actuator</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.security</groupId>
        <artifactId>spring-security-web</artifactId>
       </dependency>
    <dependency>
        <groupId>org.springframework.security</groupId>
        <artifactId>spring-security-config</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.security</groupId>
        <artifactId>spring-security-taglibs</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-data-jpa</artifactId>
    </dependency>
    <dependency>
        <groupId>commons-dbcp</groupId>
        <artifactId>commons-dbcp</artifactId>
    </dependency>
</dependencies>

la mia configurazione di ibernazione è che (la configurazione dialettale è nell'ultimo metodo di questa classe):

@Configuration
@EnableTransactionManagement
@ComponentScan({ "com.spring.app" })
public class HibernateConfig {

   @Bean
   public LocalSessionFactoryBean sessionFactory() {
      LocalSessionFactoryBean sessionFactory = new LocalSessionFactoryBean();

      sessionFactory.setDataSource(restDataSource());
      sessionFactory.setPackagesToScan(new String[] { "com.spring.app.model" });
      sessionFactory.setHibernateProperties(hibernateProperties());

      return sessionFactory;
   }

   @Bean
   public DataSource restDataSource() {
      BasicDataSource dataSource = new BasicDataSource();

      dataSource.setDriverClassName("org.postgresql.Driver");
      dataSource.setUrl("jdbc:postgresql://localhost:5432/teste?charSet=LATIN1");
      dataSource.setUsername("klebermo");
      dataSource.setPassword("123");

      return dataSource;
   }

   @Bean
   @Autowired
   public HibernateTransactionManager transactionManager(SessionFactory sessionFactory) {
      HibernateTransactionManager txManager = new HibernateTransactionManager();
      txManager.setSessionFactory(sessionFactory);
      return txManager;
   }

   @Bean
   public PersistenceExceptionTranslationPostProcessor exceptionTranslation() {
      return new PersistenceExceptionTranslationPostProcessor();
   }

   Properties hibernateProperties() {
      return new Properties() {
         /**
         * 
         */
        private static final long serialVersionUID = 1L;

        {
            setProperty("hibernate.hbm2ddl.auto", "create");
            setProperty("hibernate.show_sql", "false");
            setProperty("hibernate.dialect", "org.hibernate.dialect.PostgreSQLDialect");
         }
      };
   }
}

cosa sto facendo di sbagliato qui?

Risposte:


201

Innanzitutto rimuovi tutta la configurazione Spring Boot la avvierà per te.

Assicurati di avere un application.propertiesnel tuo percorso di classe e aggiungi le seguenti proprietà.

spring.datasource.url=jdbc:postgresql://localhost:5432/teste?charSet=LATIN1
spring.datasource.username=klebermo
spring.datasource.password=123

spring.jpa.database-platform=org.hibernate.dialect.PostgreSQLDialect
spring.jpa.show-sql=false
spring.jpa.hibernate.ddl-auto=create

Se hai davvero bisogno di accedere a SessionFactorye che è fondamentalmente per la stessa origine dati, puoi fare quanto segue (che è anche documentato qui anche se per XML, non JavaConfig).

@Configuration        
public class HibernateConfig {

    @Bean
    public HibernateJpaSessionFactoryBean sessionFactory(EntityManagerFactory emf) {
         HibernateJpaSessionFactoryBean factory = new HibernateJpaSessionFactoryBean();
         factory.setEntityManagerFactory(emf);
         return factory;
    }
}

In questo modo hai sia an EntityManagerFactoryche a SessionFactory.

AGGIORNAMENTO: A partire da Hibernate 5 in SessionFactoryrealtà estende il EntityManagerFactory. Quindi per ottenere un SessionFactorypuoi semplicemente lanciarlo EntityManagerFactoryo usare il unwrapmetodo per ottenerne uno.

public class SomeHibernateRepository {

  @PersistenceUnit
  private EntityManagerFactory emf;

  protected SessionFactory getSessionFactory() {
    return emf.unwrap(SessionFactory.class);
  }

}

Supponendo che tu abbia una classe con un mainmetodo con @EnableAutoConfigurationcui non hai bisogno @EnableTransactionManagementdell'annotazione, poiché ciò sarà abilitato da Spring Boot per te. Una classe di applicazione di base nel com.spring.apppacchetto dovrebbe essere sufficiente.

@Configuration
@EnableAutoConfiguration
@ComponentScan
public class Application {


    public static void main(String[] args) throws Exception {
        SpringApplication.run(Application.class, args);
    }

} 

Qualcosa del genere dovrebbe essere sufficiente per rilevare tutte le classi (incluse entità e repository basati su Spring Data).

AGGIORNAMENTO: queste annotazioni possono essere sostituite con una singola @SpringBootApplicationnelle versioni più recenti di Spring Boot.

@SpringBootApplication
public class Application {

    public static void main(String[] args) throws Exception {
        SpringApplication.run(Application.class, args);
    }
} 

Vorrei anche suggerire di rimuovere la commons-dbcpdipendenza in quanto ciò consentirebbe a Spring Boot di configurare l' HikariCPimplementazione più rapida e robusta .


1
ma c'è un modo per evitare di creare questo file application.propertes? Preferisco un modo in cui eseguo tutta la configurazione nella classe HibernateConfig.
Kleber Mota,

2
Perché? Lo scopo di Spring Boot è che esegue automaticamente la configurazione per te ... Quindi preferisci includere una configurazione java dettagliata su 7 righe in un file delle proprietà ?!
M. Deinum,

2
Potrebbe anche essere 6 righe in un file di proprietà. Non è necessario impostare spring.datasource.driverClassName quando si utilizza Postgres poiché Boot lo dedurrà da spring.datasource.url.
Andy Wilkinson,

2
@AlexWorden No non lo è ... Invece di inserire commenti casuali potresti prima leggere come vengono caricate le proprietà, in particolare il supporto di Spring Boot. Le password sul disco non devono essere un problema se si impostano i diritti dei file direttamente. Metterli in un database non è molto meglio ...
M. Deinum,

4
Invece di utilizzare 3 annotazioni, ad esempio Configurazione, EnableAutoConfiguration, ComponentScan. Possiamo usare l'annotazione SpringBootApplication
Pankaj

159

Stavo affrontando un problema simile all'avvio dell'applicazione (utilizzando Spring Boot) con il server di database inattivo .

Hibernate può determinare il dialetto corretto da utilizzare automaticamente, ma per fare ciò ha bisogno di una connessione live al database.


2
Il mio problema era simile a questo in quanto pg_hba.conf sul server non era configurato per la connessione remota, il che mi ha dato questo errore.
Brian,

8
Se il database a cui si sta tentando di connettersi non esiste, viene visualizzato anche questo errore.
Jonas Pedersen,

12
Ho avuto lo stesso problema, nel mio caso il DB era attivo ma le credenziali erano sbagliate. +1
Federico Piazza

sorprendentemente ho iniziato a riscontrare questo problema quando lo schema abbandonato prevedeva hbm2ddl.auto = true creerà db e tabelle. tuttavia ha fallito. ma quando ho creato lo schema vuoto hbm2ddl ha funzionato creando tabelle
Saurabh

L'IP della macchina del database è stato modificato ma un DNS si stava risolvendo in quello precedente :-(
Illidan,

24

aggiungi spring.jpa.properties.hibernate.dialect = org.hibernate.dialect.MySQLDialectnel file application.properties


Questa è un'ottima risposta - mi permette di usare un MockBean per la mia classe di database e di non avere informazioni di connessione reali nel mio profilo delle proprietà
Taylor

L'aggiunta di spring.jpa.properties.hibernate.dialect all'applicazione.properties mi ha aiutato. Grazie)
Fa

22

Ho ricevuto questo errore quando il mio database non è stato creato. Dopo aver creato il DB manualmente, ha funzionato bene.


1
Normalmente puoi evitare la creazione manuale usando "spring.jpa.hibernate.ddl-auto = create"
Andrei,

@Andrei - come / dove dovrei specificare "spring.jpa.hibernate.ddl-auto = create"?
Alex Worden,

2
@AlexWorden, Andrei voleva dire che puoi metterlo in application.properties se si tratta di Spring Boot. Ci deve essere l'equivalente per la configurazione Spring basata su XML.
ACV,

Questo errore appare solo quando il database non esiste o anche quando le tabelle all'interno del database non sono presenti?
zygimantus,

1
Avevo dato una password sbagliata e stavo affrontando lo stesso errore. Grazie ACV, mi hai aiutato molto.
santu,

17

Ho anche affrontato un problema simile. Ma era a causa della password non valida fornita. Inoltre, vorrei dire che il tuo codice sembra essere un codice vecchio stile usando spring. Hai già detto che stai utilizzando lo stivale a molla, il che significa che la maggior parte delle cose verrà configurata automaticamente per te. il dialetto ibernazione verrà selezionato automaticamente in base al driver DB disponibile sul percorso di classe insieme a credenziali valide che possono essere utilizzate per testare correttamente la connessione. In caso di problemi con la connessione, si verificherà nuovamente lo stesso errore. sono necessarie solo 3 proprietà in application.properties

# Replace with your connection string
spring.datasource.url=jdbc:mysql://localhost:3306/pdb1

# Replace with your credentials
spring.datasource.username=root
spring.datasource.password=

8

Ho riscontrato lo stesso problema e il mio problema era che il DB a cui stavo tentando di connettermi non esisteva.

Ho creato il DB, verificato l'URL / stringa di connessione e rieseguito e tutto ha funzionato come previsto.


Grazie, il tuo commento mi ha portato a verificare la porta di connessione che era errata
Feras,

4

questo sta accadendo perché il tuo codice non è balla per connettere il database. Assicurati di avere il driver mysql e il nome utente, la password corretta.


4

Assicurati di application.propertiesavere tutte le informazioni corrette: (Ho cambiato la mia porta db da 8889a 3306ha funzionato)

 db.url: jdbc:mysql://localhost:3306/test

4

In Spring Boot per jpa java config è necessario estendere JpaBaseConfiguration e implementare i suoi metodi astratti.

@Configuration
public class JpaConfig extends JpaBaseConfiguration {

    @Override
    protected AbstractJpaVendorAdapter createJpaVendorAdapter() {
        final HibernateJpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
        return vendorAdapter;
    }

    @Override
    protected Map<String, Object> getVendorProperties() {
        Map<String, Object> properties = new HashMap<>();
        properties.put("hibernate.dialect", "org.hibernate.dialect.PostgreSQLDialect");
    }

}

in alcuni casi application.properties non è in grado di vedere le modifiche alle proprietà. E ho aggiunto properties.put come sopra e ha funzionato bene. Grazie per la risposta.
Fatih Yavuz,

4

Rimuovere la configurazione di ibernazione ridondante

Se si utilizza Spring Boot, non è necessario fornire esplicitamente la configurazione JPA e Hibernate, poiché Spring Boot può farlo per te.

Aggiungi proprietà di configurazione del database

Nel application.propertiesfile di configurazione di Spring Boot, devi aggiungere le proprietà di configurazione del database:

spring.datasource.driverClassName = "org.postgresql.Driver
spring.datasource.url = jdbc:postgresql://localhost:5432/teste?charSet=LATIN1
spring.datasource.username = klebermo
spring.datasource.password = 123

Aggiungi proprietà specifiche di ibernazione

E, nello stesso application.propertiesfile di configurazione, puoi anche impostare proprietà di ibernazione personalizzate:

# Log SQL statements
spring.jpa.show-sql = false

# Hibernate ddl auto for generating the database schema
spring.jpa.hibernate.ddl-auto = create

# Hibernate database Dialect
spring.jpa.properties.hibernate.dialect = org.hibernate.dialect.PostgreSQLDialect

Questo è tutto!


L'aggiunta di spring.jpa.properties.hibernate.dialect all'applicazione.properties mi ha aiutato. Grazie)
Fa

3

Ho avuto lo stesso problema. l'aggiunta di questo a application.properties ha risolto il problema:

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

L'aggiunta di spring.jpa.properties.hibernate.dialect all'applicazione.properties mi ha aiutato. Grazie)
Fa

2

Nel mio caso l'utente non è riuscito a connettersi al database. Se avrà lo stesso problema se il registro contiene un avviso appena prima dell'eccezione:

WARN HHH000342: Could not obtain connection to query metadata : Login failed for user 'my_user'.

2

Assicurati di avere il tuo database nel tuo pom come ha fatto OP. Questo era il mio problema.


Puoi approfondire ulteriormente? Cosa intendi con questa risposta?
Tunaki,

Avevo solo bisogno di aggiungere la dipendenza mysql.
obesechicken13

2

Il mio problema era che il database incorporato era già connesso. stretta connessione


1
Posso confermare che esiste un qualche tipo di problema di ibernazione che segnala questo errore quando non riesce a connettersi. Potrei riprodurre il problema accendendo e spegnendo la rete.
Borjab,

2

Ho riscontrato questo problema quando Eclipse non è stato in grado di trovare il driver JDBC. Ho dovuto fare un aggiornamento graduale dall'eclissi per ottenere questo lavoro.


2

Di seguito sono riportati alcuni dei motivi del hibernate.dialectproblema non impostato. La maggior parte di queste eccezioni sono mostrate nel registro di avvio che è infine seguito dal problema menzionato.

Esempio: nell'app di avvio Spring con Postgres DB

1. Controllare se il database è effettivamente installato e il suo server è avviato.

  • org.postgresql.util.PSQLException: connessione a localhost: 5432 rifiutata. Verificare che il nome host e la porta siano corretti e che il postmaster accetti connessioni TCP / IP.
  • java.net.ConnectException: connessione rifiutata: connessione
  • org.hibernate.service.spi.ServiceException: Impossibile creare il servizio richiesto [org.hibernate.engine.jdbc.env.spi.JdbcEnvironment]

2. Verificare che il nome del database sia menzionato correttamente.

  • org.postgresql.util.PSQLException: FATAL: il database "foo" non esiste

    Nel application.propertiesfile,

    spring.datasource.url = jdbc:postgresql://localhost:5432/foo

    ma foonon esisteva. Quindi ho creato il database da pgAdmin per Postgres

    CREATE DATABASE foo;

3. Controllare se il nome host e la porta del server sono accessibili.

  • org.postgresql.util.PSQLException: connessione a localhost: 5431 rifiutata. Verificare che il nome host e la porta siano corretti e che il postmaster accetti connessioni TCP / IP.
  • java.net.ConnectException: connessione rifiutata: connessione

4. Controllare se le credenziali del database sono corrette.

  • come menzionato da @Pankaj
  • org.postgresql.util.PSQLException: FATAL: autenticazione password non riuscita per l'utente "postgres"

    spring.datasource.username= {DB USERNAME HERE}

    spring.datasource.password= {DB PASSWORD HERE}


1

Se stai usando questa linea:

sessionFactory.getHibernateProperties().put("hibernate.dialect", env.getProperty("hibernate.dialect"));

assicurarsi che env.getProperty("hibernate.dialect")non sia nullo.


1

Lo stesso, ma in un JBoss WildFly AS .

Risolto con proprietà nel mio META-INF/persistence.xml

<properties>
            <property name="hibernate.transaction.jta.platform"
                value="org.hibernate.service.jta.platform.internal.JBossAppServerJtaPlatform" />
            <property name="spring.jpa.database-platform" value="org.hibernate.dialect.PostgreSQLDialect" />
            <property name="spring.jpa.show-sql" value="false" />
</properties>

1

Per coloro che lavorano con AWS MySQL RDS, può verificarsi quando non si è in grado di connettersi al database. Vai alle impostazioni dei gruppi di sicurezza AWS per MySQL RDS e modifica la regola IP in entrata aggiornando MyIP.

Ho affrontato questo problema e facendo sopra ho risolto il problema per me.


Ho permesso tutto il traffico al gruppo di sicurezza di MySQL Aurora RDS, questo ha fatto il trucco per me. Se vuoi essere più specifico o per prod env, aggiungi solo ip consentiti
AleksandarT

1

Ho avuto anche questo problema. Nel mio caso è stato a causa dell'assenza di sovvenzioni assegnate all'utente MySQL. L'assegnazione di sovvenzioni all'utente MySQL che la mia app utilizza ha risolto il problema:

grant select, insert, delete, update on my_db.* to 'my_user'@'%';

1

Ho avuto lo stesso problema e dopo il debug risulta che Spring application.properties aveva un indirizzo IP errato per il server DB

spring.datasource.url=jdbc:oracle:thin:@WRONG:1521/DEV

1

Ho riprodotto questo messaggio di errore nei tre casi seguenti:

  • Non esiste un utente del database con nome utente scritto nel file application.properties o nel file persistence.properties o, come nel tuo caso, nel file HibernateConfig
  • Il database distribuito ha quell'utente ma l'utente è identificato da una password diversa da quella in uno dei file sopra
  • Il database ha quell'utente e le password corrispondono ma quell'utente non ha tutti i privilegi necessari per eseguire tutte le attività del database che l'app di avvio di primavera ha

La soluzione ovvia è quella di creare un nuovo utente del database con lo stesso nome utente e password dell'app per l'avvio a molla o modificare nome utente e password nei file dell'app per l'avvio a molla in modo che corrispondano a un utente del database esistente e concedere privilegi sufficienti a tale utente del database. Nel caso del database MySQL questo può essere fatto come mostrato di seguito:

mysql -u root -p 
>CREATE USER 'theuser'@'localhost' IDENTIFIED BY 'thepassword';
>GRANT ALL ON *.* to theuser@localhost IDENTIFIED BY 'thepassword';
>FLUSH PRIVILEGES;

Ovviamente ci sono comandi simili in Postgresql ma non ho testato se in questi tre casi questo messaggio di errore può essere riprodotto in Postgresql.


0

Ho avuto lo stesso problema ed è stato causato dall'incapacità di connettersi all'istanza del database. Cerca l'errore di ibernazione HHH000342 nel registro sopra quell'errore, dovrebbe darti un'idea di dove la connessione db non riesce (nome utente / passaggio errati, url, ecc.)


0

Questo mi è successo perché non avevo aggiunto il conf.configure();prima di iniziare la sessione:

Configuration conf = new Configuration();
conf.configure();

0

Assicurarsi di aver inserito dettagli validi in application.properties e se il proprio server di database è disponibile. Ad esempio, quando ti colleghi a MySQL, controlla se XAMPP funziona correttamente.


0

Ho riscontrato lo stesso problema: il db che stavo cercando di connettere non esisteva. Ho usato jpa.database=default(il che immagino significhi che proverà a connettersi al database e quindi a selezionare automaticamente il dialetto). Una volta avviato il database, ha funzionato bene senza alcuna modifica.


0

Ho riscontrato questo problema a causa della versione Mysql 8.0.11 che tornava alla versione 5.7 risolta per me




0

Ho avuto lo stesso errore,

 Caused by: org.hibernate.HibernateException: Access to DialectResolutionInfo cannot be null when 'hibernate.dialect' not set

nel mio caso il WAR aveva application.properties all'interno che indicava il server di sviluppo in
cui application.properties esterno puntava al server DB giusto.

assicurati di non avere altre application.properties nel classpath / jars ...

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.