org.hibernate.HibernateException: l'accès à DialectResolutionInfo ne peut pas être nul lorsque «hibernate.dialect» n'est pas défini

205

J'essaie d'exécuter une application Spring-boot qui utilise hibernate via spring-jpa, mais je reçois cette erreur:

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

mon fichier pom.xml est le suivant:

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

ma configuration de mise en veille prolongée est que (la configuration de dialecte est dans la dernière méthode de cette 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");
         }
      };
   }
}

ce que je fais mal ici?

Kleber Mota
la source

Réponses:

201

Supprimez d'abord toute votre configuration Spring Boot la démarrera pour vous.

Assurez-vous d'avoir un application.propertiesdans votre chemin de classe et ajoutez les propriétés suivantes.

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 vous avez vraiment besoin d'accéder à un SessionFactoryet c'est essentiellement pour la même source de données, vous pouvez faire ce qui suit (qui est également documenté ici bien que pour XML, pas JavaConfig).

@Configuration        
public class HibernateConfig {

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

De cette façon, vous avez à la fois un EntityManagerFactoryet un SessionFactory.

MISE À JOUR: À partir d'Hibernate 5, le SessionFactoryprolonge réellement le EntityManagerFactory. Donc, pour en obtenir un, SessionFactoryvous pouvez simplement le lancer EntityManagerFactoryou utiliser la unwrapméthode pour en obtenir un.

public class SomeHibernateRepository {

  @PersistenceUnit
  private EntityManagerFactory emf;

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

}

En supposant que vous avez une classe avec une mainméthode avec laquelle @EnableAutoConfigurationvous n'avez pas besoin de l' @EnableTransactionManagementannotation, car cela sera activé par Spring Boot pour vous. Une classe d'application de base dans le com.spring.apppackage devrait suffire.

@Configuration
@EnableAutoConfiguration
@ComponentScan
public class Application {


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

} 

Quelque chose comme ça devrait être suffisant pour que toutes vos classes (y compris les entités et les référentiels basés sur Spring Data) soient détectées.

MISE À JOUR: Ces annotations peuvent être remplacées par une seule @SpringBootApplicationdans les versions plus récentes de Spring Boot.

@SpringBootApplication
public class Application {

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

Je suggérerais également de supprimer la commons-dbcpdépendance car cela permettrait à Spring Boot de configurer l' HikariCPimplémentation plus rapide et plus robuste .

M. Deinum
la source
1
mais existe-t-il un moyen d'éviter de créer ce fichier application.propertes? Je préfère une manière où je fais toute la configuration dans la classe HibernateConfig.
Kleber Mota
2
Pourquoi? Le but de Spring Boot est de faire la configuration automatique pour vous ... Vous préférez donc inclure une configuration java verbeuse sur 7 lignes dans un fichier de propriétés?!
M. Deinum
2
Il peut même s'agir de 6 lignes dans un fichier de propriétés. Vous n'avez pas besoin de définir spring.datasource.driverClassName lorsque vous utilisez Postgres car Boot le déduira de spring.datasource.url.
Andy Wilkinson
2
@AlexWorden Non, ce n'est pas le cas ... Au lieu de mettre des commentaires aléatoires, vous voudrez peut-être d'abord lire comment les propriétés sont chargées, en particulier le support de Spring Boot. Les mots de passe sur le disque ne doivent pas être un problème si vous définissez directement les droits sur les fichiers. Les mettre dans une base de données n'est pas beaucoup mieux ...
M. Deinum
4
Au lieu d'utiliser 3 annotations, à savoir Configuration, EnableAutoConfiguration, ComponentScan. Nous pouvons utiliser l'annotation SpringBootApplication
Pankaj
159

J'étais confronté à un problème similaire lors du démarrage de l'application (à l'aide de Spring Boot) avec le serveur de base de données arrêté .

Hibernate peut déterminer le dialecte correct à utiliser automatiquement, mais pour ce faire, il a besoin d'une connexion en direct à la base de données.

mhnagaoka
la source
2
Mon problème était similaire à cela dans la mesure où pg_hba.conf sur le serveur n'était pas configuré pour la connexion à distance, ce qui m'a donné cette erreur.
Brian
8
Si la base de données à laquelle vous essayez de vous connecter n'existe pas, vous voyez également cette erreur.
Jonas Pedersen
12
Vous avez le même problème, dans mon cas, la base de données était en place mais les informations d'identification étaient fausses. +1
Federico Piazza
étonnamment, j'ai commencé à obtenir ce problème lorsque le schéma abandonné s'attendant à ce que hbm2ddl.auto = true crée une base de données et des tables. mais il a échoué. mais quand j'ai créé un schéma vide, hbm2ddl a travaillé à la création de tables
Saurabh
L'IP de la machine de la base de données a été modifiée mais un DNS était en train de se résoudre à l'ancien :-(
Illidan
24

ajouter spring.jpa.properties.hibernate.dialect = org.hibernate.dialect.MySQLDialectdans le fichier application.properties

alpin
la source
C'est une excellente réponse - me permet d'utiliser un MockBean pour ma classe de base de données et de ne pas avoir de vraies informations de connexion dans mon profil de propriétés
Taylor
L'ajout de spring.jpa.properties.hibernate.dialect à l'application.properties m'a aidé. Merci)
Maks
22

J'ai eu cette erreur lorsque ma base de données n'a pas été créée. Après avoir créé la base de données manuellement, cela a bien fonctionné.

ACV
la source
1
Normalement, vous pouvez éviter la création manuelle en utilisant "spring.jpa.hibernate.ddl-auto = create"
Andrei
@Andrei - comment / où devrais-je spécifier "spring.jpa.hibernate.ddl-auto = create"?
Alex Worden
2
@AlexWorden, Andrei signifiait que vous pouvez le mettre dans application.properties s'il s'agit de Spring Boot. Il doit y avoir l'équivalent pour la configuration Spring basée sur xml.
ACV
Cette erreur apparaît-elle uniquement lorsque la base de données n'existe pas ou également lorsque les tables à l'intérieur de la base de données ne sont pas présentes?
zygimantus
1
J'avais donné un mauvais mot de passe et je faisais face à la même erreur. Merci ACV, vous m'avez beaucoup aidé.
santu
17

J'ai également rencontré un problème similaire. Mais c'était dû au mot de passe invalide fourni. Je voudrais également dire que votre code semble être un code à l'ancienne utilisant Spring. Vous avez déjà mentionné que vous utilisez Spring Boot, ce qui signifie que la plupart des choses seront configurées automatiquement pour vous. le dialecte d'hibernation sera automatiquement sélectionné en fonction du pilote de base de données disponible sur le chemin de classe ainsi que des informations d'identification valides qui peuvent être utilisées pour tester correctement la connexion. S'il y a un problème avec la connexion, vous serez de nouveau confronté à la même erreur. seulement 3 propriétés nécessaires dans 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
la source
8

J'ai rencontré le même problème et mon problème était que la base de données à laquelle j'essayais de me connecter n'existait pas.

J'ai créé la base de données, vérifié la chaîne URL / connexion et réanimé et tout a fonctionné comme prévu.

Eric B.
la source
Merci votre commentaire m'a amené à vérifier le port de connexion qui était faux
Feras
4

cela se produit car votre code n'est pas une balle pour connecter la base de données. Assurez-vous d'avoir le pilote et le nom d'utilisateur mysql, mot de passe correct.

user7169604
la source
4

Assurez - vous que votre application.propertiesa toutes informations correctes: (j'ai changé mon port db à partir 8889de 3306cela a fonctionné)

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

Dans Spring Boot pour jpa java config, vous devez étendre JpaBaseConfiguration et implémenter ses méthodes abstraites.

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

}
Iaroslav
la source
dans certains cas, application.properties ne peut pas voir les modifications des propriétés.Et j'ai ajouté properties.put comme ci-dessus et j'ai bien fonctionné.Thx pour la réponse.
fatih yavuz
4

Supprimer la configuration Hibernate redondante

Si vous utilisez Spring Boot, vous n'avez pas besoin de fournir explicitement la configuration JPA et Hibernate, car Spring Boot peut le faire pour vous.

Ajouter des propriétés de configuration de base de données

Dans le application.propertiesfichier de configuration Spring Boot, vous devez ajouter les propriétés de configuration de votre base de données:

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

Ajouter des propriétés spécifiques à Hibernate

Et, dans le même application.propertiesfichier de configuration, vous pouvez également définir des propriétés Hibernate personnalisées:

# 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

C'est tout!

Vlad Mihalcea
la source
L'ajout de spring.jpa.properties.hibernate.dialect à l'application.properties m'a aidé. Merci)
Maks
3

J'ai eu le même problème. l'ajout de cela à l'application.properties a résolu le problème:

spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQLDialect
Arthur Kazemi
la source
L'ajout de spring.jpa.properties.hibernate.dialect à l'application.properties m'a aidé. Merci)
Maks
2

Dans mon cas, l'utilisateur n'a pas pu se connecter à la base de données. Si aura le même problème si le journal contient un avertissement juste avant l'exception:

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

Assurez-vous d'avoir votre base de données dans votre pom comme OP l'a fait. C'était mon problème.

obesechicken13
la source
Pouvez-vous développer davantage? Que voulez-vous dire par cette réponse?
Tunaki
J'avais juste besoin d'ajouter la dépendance mysql.
obesechicken13
2

Mon problème était que la base de données intégrée était déjà connectée. fermer la connexion

doesnt_matter
la source
1
Je peux confirmer qu'il existe une sorte de problème Hibernate qui signale cette erreur lorsqu'il ne parvient pas à se connecter. Je pourrais reproduire le problème d'allumer et d'éteindre le réseau.
borjab
2

J'ai eu ce problème quand Eclipse n'a pas pu trouver le pilote JDBC. J'ai dû faire un rafraîchissement graduel de l'éclipse pour obtenir ce travail.

Kannan Ramamoorthy
la source
2

Voici quelques-unes des raisons du hibernate.dialectproblème non défini. La plupart de ces exceptions sont affichées dans le journal de démarrage qui est finalement suivi du problème mentionné.

Exemple: dans l'application de démarrage Spring avec Postgres DB

1. Vérifiez si la base de données est réellement installée et que son serveur est démarré.

  • org.postgresql.util.PSQLException: connexion à l'hôte local: 5432 refusée. Vérifiez que le nom d'hôte et le port sont corrects et que le postmaster accepte les connexions TCP / IP.
  • java.net.ConnectException: connexion refusée: connexion
  • org.hibernate.service.spi.ServiceException: impossible de créer le service demandé [org.hibernate.engine.jdbc.env.spi.JdbcEnvironment]

2. Vérifiez si le nom de la base de données est correctement mentionné.

  • org.postgresql.util.PSQLException: FATAL: la base de données "foo" n'existe pas

    En application.propertiesdossier,

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

    mais foon'existait pas. J'ai donc créé la base de données de pgAdmin pour postgres

    CREATE DATABASE foo;

3. Vérifiez si le nom d'hôte et le port du serveur sont accessibles.

  • org.postgresql.util.PSQLException: connexion à localhost: 5431 refusée. Vérifiez que le nom d'hôte et le port sont corrects et que le postmaster accepte les connexions TCP / IP.
  • java.net.ConnectException: connexion refusée: connexion

4. Vérifiez si les informations d'identification de la base de données sont correctes.

  • comme @Pankaj l'a mentionné
  • org.postgresql.util.PSQLException: FATAL: l'authentification par mot de passe a échoué pour l'utilisateur "postgres"

    spring.datasource.username= {DB USERNAME HERE}

    spring.datasource.password= {DB PASSWORD HERE}

abitcode
la source
1

Si vous utilisez cette ligne:

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

assurez-vous que ce env.getProperty("hibernate.dialect")n'est pas nul.

zygimantus
la source
1

Idem mais dans un JBoss WildFly AS .

Résolu avec des propriétés dans mon 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
la source
1

Pour ceux qui travaillent avec AWS MySQL RDS, cela peut se produire lorsque vous ne parvenez pas à vous connecter à la base de données. Accédez au paramètre AWS Security Groups pour MySQL RDS et modifiez la règle IP entrante en actualisant MyIP.

J'ai rencontré ce problème et faire ci-dessus a résolu le problème pour moi.

Ajitesh
la source
J'ai autorisé tout le trafic vers le groupe de sécurité du RDS Aurora MySQL, cela a fait l'affaire pour moi. Si vous voulez être plus précis ou pour prod env, ajoutez uniquement les ips autorisés
AleksandarT
1

J'ai aussi eu ce problème. Dans mon cas, c'est parce qu'aucune subvention n'a été attribuée à l'utilisateur MySQL. L'attribution de subventions à l'utilisateur MySQL que mon application utilise a résolu le problème:

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

J'ai eu le même problème et après le débogage, il s'avère que Spring application.properties avait une mauvaise adresse IP pour le serveur DB

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

J'ai reproduit ce message d'erreur dans les trois cas suivants:

  • Il n'existe pas d'utilisateur de base de données avec un nom d'utilisateur écrit dans le fichier application.properties ou le fichier persistence.properties ou, comme dans votre cas, dans le fichier HibernateConfig
  • La base de données déployée a cet utilisateur, mais l'utilisateur est identifié par un mot de passe différent de celui de l'un des fichiers ci-dessus
  • La base de données a cet utilisateur et les mots de passe correspondent, mais cet utilisateur n'a pas tous les privilèges nécessaires pour accomplir toutes les tâches de base de données que votre application Spring-boot fait

La solution évidente consiste à créer un nouvel utilisateur de base de données avec les mêmes nom d'utilisateur et mot de passe que dans l'application Spring-Boot ou à changer le nom d'utilisateur et le mot de passe dans vos fichiers d'application Spring-Boot pour correspondre à un utilisateur de base de données existant et accorder des privilèges suffisants à cet utilisateur de base de données. Dans le cas d'une base de données MySQL, cela peut être fait comme indiqué ci-dessous:

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

Évidemment, il existe des commandes similaires dans Postgresql mais je n'ai pas testé si dans le cas de Postgresql ce message d'erreur peut être reproduit dans ces trois cas.

Veli-Matti Sorvala
la source
0

J'ai eu le même problème et il a été causé par l'impossibilité de se connecter à l'instance de base de données. Recherchez l'erreur de mise en veille prolongée HHH000342 dans le journal au-dessus de cette erreur, cela devrait vous donner une idée de l'endroit où la connexion db échoue (nom d'utilisateur / passe incorrect, URL, etc.)

Farouk
la source
0

Cela m'est arrivé car je n'avais pas ajouté le conf.configure();avant de commencer la session:

Configuration conf = new Configuration();
conf.configure();
Diane
la source
0

Assurez-vous que vous avez entré des détails valides dans application.properties et si votre serveur de base de données est disponible. Par exemple, lorsque vous vous connectez avec MySQL, vérifiez si XAMPP fonctionne correctement.

Lahiru Gamage
la source
0

J'ai rencontré le même problème: la base de données que j'essayais de connecter n'existait pas. J'ai utilisé jpa.database=default(ce qui signifie, je suppose, qu'il essaiera de se connecter à la base de données, puis de sélectionner automatiquement le dialecte). Une fois que j'ai démarré la base de données, cela a bien fonctionné sans aucun changement.

Avishekh Tewari
la source
0

J'ai rencontré ce problème en raison du retour de la version Mysql 8.0.11 à 5.7 résolu pour moi

Gautam Yadav
la source
0

J'ai eu la même erreur,

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

dans mon cas, le fichier WAR contenait application.properties qui pointait vers un serveur de développement
où application.properties externe pointait vers le bon serveur de base de données.

assurez-vous que vous n'avez pas d'autre application.properties dans le classpath / jars ...

JavaSheriff
la source