org.hibernate.HibernateException: el acceso a DialectResolutionInfo no puede ser nulo cuando no se establece 'hibernate.dialect'

205

Estoy intentando ejecutar una aplicación spring-boot que usa hibernate a través de spring-jpa, pero recibo este error:

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

mi archivo pom.xml es este:

<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>

mi configuración de hibernación es que (la configuración del dialecto está en el último método de esta clase):

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

¿Qué estoy haciendo mal aquí?

Kleber Mota
fuente

Respuestas:

201

Primero elimine toda su configuración Spring Boot lo iniciará por usted.

Asegúrese de tener un application.propertiesen su classpath y agregue las siguientes propiedades.

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

Si realmente necesita acceso a ay SessionFactoryeso es básicamente para el mismo origen de datos, puede hacer lo siguiente (que también se documenta aquí, aunque para XML, no JavaConfig).

@Configuration        
public class HibernateConfig {

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

De esa manera tienes tanto an EntityManagerFactorycomo a SessionFactory.

ACTUALIZACIÓN: A partir de Hibernate 5, en SessionFactoryrealidad se extiende el EntityManagerFactory. Entonces, para obtener SessionFactoryuno, simplemente puede lanzarlo EntityManagerFactoryo usar el unwrapmétodo para obtener uno.

public class SomeHibernateRepository {

  @PersistenceUnit
  private EntityManagerFactory emf;

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

}

Suponiendo que tiene una clase con un mainmétodo con el @EnableAutoConfigurationque no necesita la @EnableTransactionManagementanotación, ya que Spring Boot lo habilitará para usted. Una clase de aplicación básica en el com.spring.apppaquete debería ser suficiente.

@Configuration
@EnableAutoConfiguration
@ComponentScan
public class Application {


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

} 

Algo así debería ser suficiente para que se detecten todas sus clases (incluidas las entidades y los repositorios basados ​​en Spring Data).

ACTUALIZACIÓN: Estas anotaciones se pueden reemplazar con una sola @SpringBootApplicationen las versiones más recientes de Spring Boot.

@SpringBootApplication
public class Application {

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

También sugeriría eliminar la commons-dbcpdependencia ya que eso permitiría a Spring Boot configurar la HikariCPimplementación más rápida y robusta .

M. Deinum
fuente
1
pero hay alguna forma de evitar crear este archivo application.propertes? Prefiero una forma en la que hago toda la configuración en la clase HibernateConfig.
Kleber Mota
2
¿Por qué? Todo el propósito de Spring Boot es que realiza la configuración automática para usted ... ¿Entonces prefiere incluir una configuración detallada de Java sobre 7 líneas en un archivo de propiedades?
M. Deinum
2
Incluso podría tener 6 líneas en un archivo de propiedades. No necesita establecer spring.datasource.driverClassName cuando usa Postgres ya que Boot lo inferirá de spring.datasource.url.
Andy Wilkinson
2
@AlexWorden No, no lo es ... En lugar de poner comentarios al azar, es posible que primero desee leer cómo se cargan las propiedades, especialmente el soporte que tiene Spring Boot. Las contraseñas en el disco no tienen que ser un problema si establece los derechos de archivo directamente. Ponerlos en una base de datos no es mucho mejor ...
M. Deinum
44
En lugar de usar 3 anotaciones, es decir, Configuración, EnableAutoConfiguration, ComponentScan. Podemos usar la anotación SpringBootApplication
Pankaj
159

Estaba enfrentando un problema similar al iniciar la aplicación (usando Spring Boot) con el servidor de base de datos inactivo .

Hibernate puede determinar el dialecto correcto para usar automáticamente, pero para hacer esto, necesita una conexión en vivo a la base de datos.

mhnagaoka
fuente
2
Mi problema era similar a esto en que pg_hba.conf en el servidor no estaba configurado para la conexión remota, lo que me dio este error.
Brian
8
Si la base de datos a la que intenta conectarse no existe, también verá este error.
Jonas Pedersen
12
Tengo el mismo problema, en mi caso el DB estaba arriba pero las credenciales estaban equivocadas. +1
Federico Piazza
Sorprendentemente, comencé a tener este problema cuando se cayó el esquema esperando que hbm2ddl.auto = true creará db y tablas. Sin embargo, falló. pero cuando creé un esquema vacío, hbm2ddl trabajó creando tablas
Saurabh
La IP de la máquina de la base de datos ha sido cambiada pero un DNS se estaba resolviendo a la anterior :-(
Illidan
24

agregar spring.jpa.properties.hibernate.dialect = org.hibernate.dialect.MySQLDialecten el archivo application.properties

alpino
fuente
Esta es una gran respuesta: me permite usar un MockBean para mi clase de base de datos y no tener información de conexión real en mi perfil de propiedades
Taylor
Agregar spring.jpa.properties.hibernate.dialect a la application.properties me ayudó. Gracias)
Maks
22

Recibí este error cuando mi base de datos no fue creada. Después de crear la base de datos manualmente, funcionó bien.

ACV
fuente
1
Normalmente puede evitar la creación manual utilizando "spring.jpa.hibernate.ddl-auto = create"
Andrei
@Andrei: ¿cómo / dónde especificaría "spring.jpa.hibernate.ddl-auto = create"?
Alex Worden
2
@AlexWorden, Andrei quería decir que puedes ponerlo en application.properties si es Spring Boot. Debe haber el equivalente para la configuración Spring basada en xml.
ACV
¿Aparece este error solo cuando la base de datos no existe o también cuando las tablas dentro de la base de datos no están presentes?
zygimantus
1
Había dado una contraseña incorrecta y estaba enfrentando el mismo error. Gracias ACV, me ayudaste mucho.
santu
17

También me enfrenté a un problema similar. Pero, se debió a la contraseña no válida proporcionada. Además, me gustaría decir que su código parece ser un código antiguo que usa spring. Ya mencionaste que estás usando Spring Boot, lo que significa que la mayoría de las cosas se configurarán automáticamente para ti. el dialecto de hibernación se seleccionará automáticamente en función del controlador de DB disponible en el classpath junto con credenciales válidas que se pueden usar para probar la conexión correctamente. Si hay algún problema con la conexión, nuevamente enfrentará el mismo error. solo se necesitan 3 propiedades en 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=
Pankaj
fuente
8

Me encontré con el mismo problema y mi problema era que el DB al que intentaba conectarme no existía.

Creé la base de datos, verifiqué la cadena de conexión / URL y volví a ejecutar y todo funcionó como se esperaba.

Eric B.
fuente
Gracias, tu comentario me llevó a verificar el puerto de conexión que estaba mal
Feras
4

Esto sucede porque su código no está preparado para conectar la base de datos. Asegúrese de tener el controlador mysql y el nombre de usuario, la contraseña correcta.

usuario7169604
fuente
4

Asegúrese de que application.propertiestenga toda la información correcta: (cambié mi puerto db de 8889a 3306funcionó)

 db.url: jdbc:mysql://localhost:3306/test
Vikram S
fuente
4

En el arranque de primavera para jpa java config necesita extender JpaBaseConfiguration e implementar sus métodos abstractos.

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

}
Yaroslav
fuente
en algunos casos, application.properties no puede ver los cambios en las propiedades. Y agregué properties.put como arriba y funcionó bien. Gracias por responder.
Fatih Yavuz
4

Eliminar la configuración de hibernación redundante

Si está utilizando Spring Boot, no necesita proporcionar la configuración JPA e Hibernate explícitamente, ya que Spring Boot puede hacerlo por usted.

Agregar propiedades de configuración de la base de datos

En el application.propertiesarchivo de configuración de Spring Boot, debe agregar las propiedades de configuración de su base de datos:

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

Agregar propiedades específicas de Hibernate

Y, en el mismo application.propertiesarchivo de configuración, también puede establecer propiedades personalizadas de Hibernate:

# 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

¡Eso es!

Vlad Mihalcea
fuente
Agregar spring.jpa.properties.hibernate.dialect a la application.properties me ayudó. Gracias)
Maks
3

Tuve el mismo problema agregando esto a la aplicación. las propiedades resolvieron el problema:

spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQLDialect
Arthur Kazemi
fuente
Agregar spring.jpa.properties.hibernate.dialect a la application.properties me ayudó. Gracias)
Maks
2

En mi caso, el usuario no pudo conectarse a la base de datos. Si tendrá el mismo problema si el registro contiene una advertencia justo antes de la excepción:

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

Asegúrese de tener su base de datos en su pom como lo hizo OP. Ese fue mi problema.

obeso
fuente
¿Puedes elaborar más? ¿Qué quieres decir con esta respuesta?
Tunaki
Solo necesitaba agregar la dependencia mysql.
obesechicken13
2

Mi problema fue que la base de datos incrustada ya estaba conectada. conexión cercana

no importa
fuente
1
Puedo confirmar que hay algún tipo de problema de Hibernate que informa este error cuando no se conecta. Podría reproducir el problema al encender y apagar la red.
borjab
2

Recibí este problema cuando Eclipse no pudo encontrar el controlador JDBC. Tuve que hacer una actualización de Gradle desde el eclipse para conseguir este trabajo.

Kannan Ramamoorthy
fuente
2

Las siguientes son algunas de las razones del hibernate.dialectproblema no establecido. La mayoría de estas excepciones se muestran en el registro de inicio, que finalmente es seguido por el problema mencionado.

Ejemplo: en la aplicación de arranque de Spring con Postgres DB

1. Compruebe si la base de datos está realmente instalada y su servidor está iniciado.

  • org.postgresql.util.PSQLException: Conexión a localhost: 5432 rechazada. Verifique que el nombre de host y el puerto sean correctos y que el administrador de correo acepte conexiones TCP / IP.
  • java.net.ConnectException: Conexión rechazada: conectar
  • org.hibernate.service.spi.ServiceException: no se puede crear el servicio solicitado [org.hibernate.engine.jdbc.env.spi.JdbcEnvironment]

2. Compruebe si el nombre de la base de datos se menciona correctamente.

  • org.postgresql.util.PSQLException: FATAL: la base de datos "foo" no existe

    En application.propertiesarchivo,

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

    Pero foono existía. Entonces creé la base de datos de pgAdmin para postgres

    CREATE DATABASE foo;

3. Compruebe si el nombre de host y el puerto del servidor son accesibles.

  • org.postgresql.util.PSQLException: Conexión a localhost: 5431 rechazado. Verifique que el nombre de host y el puerto sean correctos y que el administrador de correo acepte conexiones TCP / IP.
  • java.net.ConnectException: Conexión rechazada: conectar

4. Compruebe si las credenciales de la base de datos son correctas.

  • como @Pankaj mencionó
  • org.postgresql.util.PSQLException: FATAL: la autenticación de contraseña falló para el usuario "postgres"

    spring.datasource.username= {DB USERNAME HERE}

    spring.datasource.password= {DB PASSWORD HERE}

abitcode
fuente
1

Si está utilizando esta línea:

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

asegúrese de que env.getProperty("hibernate.dialect")no sea nulo.

zygimantus
fuente
1

Lo mismo pero en un JBoss WildFly AS .

Resuelto con propiedades en mi 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>
Alejandro Teixeira Muñoz
fuente
1

Para aquellos que trabajan con AWS MySQL RDS, puede ocurrir cuando no puede conectarse a la base de datos. Vaya a la configuración de Grupos de seguridad de AWS para MySQL RDS y edite la regla de IP entrante actualizando MyIP.

Me enfrenté a este problema y hacer lo anterior solucionó el problema para mí.

Ajitesh
fuente
Permití todo el tráfico al grupo de seguridad del RDS Aurora MySQL, esto me sirvió. Si desea ser más específico o para un entorno de producción, agregue solo los ips permitidos
AleksandarT
1

Yo también tuve este problema. En mi caso fue porque no se asignaron subvenciones al usuario de MySQL. La asignación de subvenciones al usuario de MySQL que utiliza mi aplicación resolvió el problema:

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

Tuve el mismo problema y después de la depuración resultó que Spring application.properties tenía una dirección IP incorrecta para el servidor DB

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

Reproduje este mensaje de error en los siguientes tres casos:

  • No existe un usuario de la base de datos con un nombre de usuario escrito en el archivo application.properties o en el archivo persistence.properties o, como en su caso, en el archivo HibernateConfig
  • La base de datos desplegada tiene ese usuario, pero el usuario se identifica con una contraseña diferente a la de uno de los archivos anteriores
  • La base de datos tiene ese usuario y las contraseñas coinciden, pero ese usuario no tiene todos los privilegios necesarios para llevar a cabo todas las tareas de la base de datos que realiza su aplicación Spring-boot

La solución obvia es crear un nuevo usuario de la base de datos con el mismo nombre de usuario y contraseña que en la aplicación spring-boot o cambiar el nombre de usuario y la contraseña en los archivos de la aplicación spring-boot para que coincida con un usuario de la base de datos existente y otorgar privilegios suficientes a ese usuario de la base de datos. En el caso de la base de datos MySQL, esto se puede hacer como se muestra a continuación:

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

Obviamente, hay comandos similares en Postgresql, pero no he probado si en el caso de Postgresql este mensaje de error se puede reproducir en estos tres casos.

Veli-Matti Sorvala
fuente
0

Tuve el mismo problema y fue causado por no poder conectarme a la instancia de la base de datos. Busque el error de hibernación HHH000342 en el registro arriba de ese error, debería darle una idea de dónde falla la conexión db (nombre de usuario / contraseña, url, etc. incorrectos)

Farouk
fuente
0

Esto me sucedió porque no había agregado el conf.configure();antes de comenzar la sesión:

Configuration conf = new Configuration();
conf.configure();
Diana
fuente
0

Asegúrese de haber ingresado detalles válidos en application.properties y si su servidor de base de datos está disponible. Como ejemplo, cuando se conecta con MySQL, compruebe si XAMPP se está ejecutando correctamente.

Daño de Lahiru
fuente
0

Me enfrenté al mismo problema: la base de datos que intentaba conectar no existía. Usé jpa.database=default(lo que supongo que significa que intentará conectarse a la base de datos y luego seleccionará automáticamente el dialecto). Una vez que comencé la base de datos, funcionó bien sin ningún cambio.

Avishekh Tewari
fuente
0

Enfrenté este problema debido a que la versión de Mysql 8.0.11 volviendo a 5.7 resuelta para mí

Gautam Yadav
fuente
0

Yo tenía el mismo error,

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

en mi caso, WAR tenía aplicaciones.properties dentro que apuntaban al servidor de desarrollo
donde application.properties externo apuntaba al servidor de base de datos correcto.

asegúrese de no tener ninguna otra aplicación. propiedades en el classpath / jars ...

JavaSheriff
fuente