org.hibernate.HibernateException: o acesso ao DialectResolutionInfo não pode ser nulo quando 'hibernate.dialect' não está definido

205

Estou tentando executar um aplicativo spring-boot que usa o hibernate via spring-jpa, mas estou recebendo este erro:

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

meu arquivo pom.xml é 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>

minha configuração de hibernação é a seguinte (a configuração de dialeto está no último método desta 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");
         }
      };
   }
}

o que estou fazendo de errado aqui?

Kleber Mota
fonte

Respostas:

201

Primeiro remova todas as suas configurações que o Spring Boot iniciará para você.

Verifique se você possui um application.propertiescaminho de classe e adicione as seguintes propriedades.

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 você realmente precisar acessar ae SessionFactorybasicamente para a mesma fonte de dados, poderá fazer o seguinte (que também está documentado aqui, embora seja para XML, não para JavaConfig).

@Configuration        
public class HibernateConfig {

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

Dessa forma, você tem um EntityManagerFactorye um SessionFactory.

ATUALIZAÇÃO: A partir do Hibernate 5, na SessionFactoryverdade, estende o EntityManagerFactory. Portanto, para obter um, SessionFactoryvocê pode simplesmente convertê EntityManagerFactory-lo ou usar o unwrapmétodo para obter um.

public class SomeHibernateRepository {

  @PersistenceUnit
  private EntityManagerFactory emf;

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

}

Supondo que você tenha uma classe com um mainmétodo @EnableAutoConfiguration, não precisa da @EnableTransactionManagementanotação, pois isso será ativado pelo Spring Boot para você. Uma classe de aplicativo básica no com.spring.apppacote deve ser suficiente.

@Configuration
@EnableAutoConfiguration
@ComponentScan
public class Application {


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

} 

Algo assim deve ser suficiente para que todas as suas classes (incluindo entidades e repositórios baseados em Spring Data) sejam detectadas.

ATUALIZAÇÃO: essas anotações podem ser substituídas por uma única @SpringBootApplicationnas versões mais recentes do Spring Boot.

@SpringBootApplication
public class Application {

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

Eu também sugeriria remover a commons-dbcpdependência, pois isso permitiria ao Spring Boot configurar a HikariCPimplementação mais rápida e robusta .

M. Deinum
fonte
1
mas existe alguma maneira de evitar criar este arquivo application.propertes? Eu prefiro uma maneira de fazer toda a configuração na classe HibernateConfig.
Kleber Mota
2
Por quê? Todo o objetivo do Spring Boot é que ele faça a configuração automática para você ... Então, você prefere incluir uma configuração Java detalhada em 7 linhas em um arquivo de propriedades ?!
M. Deinum 24/10
2
Pode até ter 6 linhas em um arquivo de propriedades. Você não precisa definir spring.datasource.driverClassName quando estiver usando o Postgres, pois o Boot o inferirá a partir de spring.datasource.url.
Andy Wilkinson
2
@AlexWorden Não, não é ... Em vez de colocar comentários aleatórios, primeiro você deve ler como as propriedades são carregadas, especialmente o suporte que o Spring Boot possui. As senhas no disco não precisam ser um problema se você definir os direitos de arquivo corretamente. Colocá-los em um banco de dados não é muito melhor ...
M. Deinum 13/15
4
Em vez de usar 3 anotações, isto é, Configuração, EnableAutoConfiguration, ComponentScan. Podemos usar a anotação SpringBootApplication
Pankaj 8/15
159

Eu estava enfrentando um problema semelhante ao iniciar o aplicativo (usando o Spring Boot) com o servidor de banco de dados inativo .

O Hibernate pode determinar o dialeto correto a ser usado automaticamente, mas para fazer isso, ele precisa de uma conexão ativa com o banco de dados.

mhnagaoka
fonte
2
Meu problema foi semelhante ao do pg_hba.conf no servidor não estar configurado para a conexão remota, o que me deu esse erro.
Brian
8
Se o banco de dados ao qual você está tentando se conectar não existir, você também verá esse erro.
Jonas Pedersen
12
Tenho o mesmo problema, no meu caso, o banco de dados estava ativo, mas as credenciais estavam erradas. +1
Federico Piazza
surpreendentemente, comecei a obter esse problema quando o esquema descartado esperava que hbm2ddl.auto = true criará bancos de dados e tabelas. no entanto, falhou. mas wen i criado hbm2ddl esquema vazio trabalhou criação de tabelas
Saurabh
IP da máquina de banco de dados foi alterado, mas um DNS foi resolvendo o antigo :-(
Illidan
24

adicionar spring.jpa.properties.hibernate.dialect = org.hibernate.dialect.MySQLDialectno arquivo application.properties

alpino
fonte
Esta é uma grande resposta - me permite usar uma MockBean para minha classe de banco de dados e não tem informações de conexão real no meu perfil propriedades
Taylor
Adicionar spring.jpa.properties.hibernate.dialect ao application.properties me ajudou. Obrigado)
Maks
22

Eu recebi esse erro quando meu banco de dados não foi criado. Depois de criar o banco de dados manualmente, funcionou bem.

ACV
fonte
1
Normalmente você pode evitar a criação manual usando "spring.jpa.hibernate.ddl-auto = create"
Andrei
@Andrei - como / onde eu especificaria "spring.jpa.hibernate.ddl-auto = create"?
Alex Worden
2
@AlexWorden, Andrei significava que você pode colocá-lo em application.properties se for Spring Boot. Deve haver o equivalente para a configuração Spring baseada em xml.
ACV
Este erro aparece apenas quando o banco de dados não existe ou também quando as tabelas dentro do banco de dados não estão presentes?
Zygimantus
1
Eu tinha dado a senha errada e estava enfrentando o mesmo erro. Obrigado ACV, você me ajudou muito.
santu
17

Eu também enfrentei um problema semelhante. Mas isso ocorreu devido à senha inválida fornecida. Além disso, gostaria de dizer que seu código parece ser antigo usando a primavera. Você já mencionou que está usando a bota de mola, o que significa que a maioria das coisas será configurada automaticamente para você. O dialeto de hibernação será selecionado automaticamente com base no driver DB disponível no caminho de classe, juntamente com credenciais válidas que podem ser usadas para testar a conexão corretamente. Se houver algum problema com a conexão, você novamente enfrentará o mesmo erro. são necessárias apenas 3 propriedades em 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
fonte
8

Encontrei o mesmo problema e meu problema era que o banco de dados ao qual estava tentando conectar não existia.

Criei o banco de dados, verifiquei a URL / string de conexão e reran e tudo funcionou conforme o esperado.

Eric B.
fonte
Obrigado comentário me levou para verificar a porta de conexão que estava errado
Feras
4

isso está acontecendo porque seu código não é fardo para conectar o banco de dados. Verifique se você possui o driver mysql e o nome de usuário, a senha correta.

user7169604
fonte
4

Verifique se application.propertiestodas as informações estão corretas: (mudei minha porta db 8889para a 3306que funcionou)

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

Na inicialização do Spring para jpa java config, você precisa estender o JpaBaseConfiguration e implementar seus métodos abstratos.

@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
fonte
Em alguns casos, application.properties não pode ver as propriedades alteradas. E adicionei properties.put, como acima, e funcionou bem.
fatih yavuz 19/02
4

Remova a configuração de hibernação redundante

Se você estiver usando o Spring Boot, não precisará fornecer explicitamente a configuração JPA e Hibernate, pois o Spring Boot pode fazer isso por você.

Adicionar propriedades de configuração do banco de dados

No application.propertiesarquivo de configuração do Spring Boot, adicione as propriedades de configuração do banco de dados:

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

Adicionar propriedades específicas do Hibernate

E, no mesmo application.propertiesarquivo de configuração, você também pode definir propriedades personalizadas do 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

É isso aí!

Vlad Mihalcea
fonte
Adicionar spring.jpa.properties.hibernate.dialect ao application.properties me ajudou. Obrigado)
Maks
3

Eu tive o mesmo problema. adicionar isso ao application.properties resolveu o problema:

spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQLDialect
Arthur Kazemi
fonte
Adicionar spring.jpa.properties.hibernate.dialect ao application.properties me ajudou. Obrigado)
Maks
2

No meu caso, o usuário não pôde se conectar ao banco de dados. Se terá o mesmo problema se o log contiver um aviso antes da exceção:

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

Certifique-se de ter seu banco de dados no seu pom, como o OP. Esse foi o meu problema.

obesechicken13
fonte
Você pode elaborar mais? O que você quer dizer com esta resposta?
Tunaki
Eu só precisava adicionar a dependência do mysql.
obesechicken13
2

Meu problema era que o banco de dados incorporado já estava conectado. conexão próxima

doesnt_matter
fonte
1
Posso confirmar que há algum tipo de problema de hibernação que relata esse erro quando ele falha na conexão. Eu pude reproduzir o problema de ligar e desligar a rede.
borjab
2

Eu obtive esse problema quando o Eclipse não conseguiu encontrar o driver JDBC. Tive que fazer uma atualização gradual do eclipse para obter esse trabalho.

Kannan Ramamoorthy
fonte
2

A seguir, estão alguns dos motivos para a hibernate.dialect problema não definido. A maioria dessas exceções é mostrada no log de inicialização, que é finalmente seguido pelo problema mencionado.

Exemplo: no aplicativo de inicialização Spring com o Postgres DB

1. Verifique se o banco de dados está realmente instalado e se o servidor foi iniciado.

  • org.postgresql.util.PSQLException: Conexão com o host local: 5432 recusada. Verifique se o nome do host e a porta estão corretos e se o postmaster está aceitando conexões TCP / IP.
  • java.net.ConnectException: conexão recusada: conectar
  • org.hibernate.service.spi.ServiceException: Não foi possível criar o serviço solicitado [org.hibernate.engine.jdbc.env.spi.JdbcEnvironment]

2. Verifique se o nome do banco de dados está mencionado corretamente.

  • org.postgresql.util.PSQLException: FATAL: o banco de dados "foo" não existe

    Em application.propertiesarquivo,

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

    mas foonão existia. Então eu criei o banco de dados a partir do pgAdmin para o postgres

    CREATE DATABASE foo;

3. Verifique se o nome do host e a porta do servidor estão acessíveis.

  • org.postgresql.util.PSQLException: Conexão com o host local: 5431 recusada. Verifique se o nome do host e a porta estão corretos e se o postmaster está aceitando conexões TCP / IP.
  • java.net.ConnectException: conexão recusada: conectar

4. Verifique se as credenciais do banco de dados estão corretas.

  • como @Pankaj mencionado
  • org.postgresql.util.PSQLException: FATAL: falha na autenticação da senha para o usuário "postgres"

    spring.datasource.username= {DB USERNAME HERE}

    spring.datasource.password= {DB PASSWORD HERE}

abitcode
fonte
1

Se você estiver usando esta linha:

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

verifique se env.getProperty("hibernate.dialect")não é nulo.

zygimantus
fonte
1

O mesmo, mas em um JBoss WildFly AS .

Resolvido com propriedades no meu 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
fonte
1

Para aqueles que trabalham com o AWS MySQL RDS, isso pode ocorrer quando você não consegue se conectar ao banco de dados. Vá para a configuração de Grupos de segurança da AWS para MySQL RDS e edite a regra de IP de entrada atualizando o MyIP.

Eu enfrentei esse problema e, acima, resolvi o problema para mim.

Ajitesh
fonte
Eu permiti todo o tráfego para o grupo de segurança do MySQL RDS Aurora, isso fez o truque para mim. Se você quiser ser mais específico ou produzir mais, adicione apenas os ips permitidos
AleksandarT
1

Eu também tive esse problema. No meu caso, foi por causa de nenhuma concessão ter sido atribuída ao usuário do MySQL. A atribuição de concessões ao usuário MySQL que meu aplicativo usa resolveu o problema:

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

Eu tive o mesmo problema e, após a depuração, verifica-se que o Spring application.properties tinha um endereço IP incorreto para o servidor DB

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

Reproduzi essa mensagem de erro nos três casos a seguir:

  • Não existe usuário do banco de dados com nome de usuário gravado no arquivo application.properties ou no arquivo persistence.properties ou, como no seu caso, no arquivo HibernateConfig
  • O banco de dados implantado possui esse usuário, mas o usuário é identificado por uma senha diferente daquela em um dos arquivos acima
  • O banco de dados possui esse usuário e as senhas correspondentes, mas esse usuário não possui todos os privilégios necessários para realizar todas as tarefas do banco de dados executadas pelo aplicativo de inicialização por primavera

A solução óbvia é criar um novo usuário de banco de dados com o mesmo nome de usuário e senha do aplicativo de inicialização por mola ou alterar o nome de usuário e a senha nos arquivos do aplicativo de inicialização por inicialização para corresponder a um usuário de banco de dados existente e conceder privilégios suficientes para esse usuário de banco de dados. No caso do banco de dados MySQL, isso pode ser feito conforme mostrado abaixo:

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

Obviamente, existem comandos semelhantes no Postgresql, mas não testei se, no caso do Postgresql, essa mensagem de erro pode ser reproduzida nesses três casos.

Veli-Matti Sorvala
fonte
0

Eu tive o mesmo problema e foi causado por não conseguir conectar-se à instância do banco de dados. Procure o erro de hibernação HHH000342 no log acima desse erro; ele deve dar uma idéia de onde a conexão db está falhando (nome de usuário / senha incorreto, URL, etc.)

Farouk
fonte
0

Isso aconteceu comigo porque eu não tinha adicionado o conf.configure();antes de iniciar a sessão:

Configuration conf = new Configuration();
conf.configure();
diana
fonte
0

Certifique-se de inserir detalhes válidos em application.properties e se seu servidor de banco de dados está disponível. Como exemplo, quando você está se conectando ao MySQL, verifique se o XAMPP está sendo executado corretamente.

Lahiru Gamage
fonte
0

Eu enfrentei o mesmo problema: o banco de dados que estava tentando conectar não existia. Eu usei jpa.database=default(o que eu acho que significa que ele tentará se conectar ao banco de dados e depois selecionar automaticamente o dialeto). Depois que iniciei o banco de dados, ele funcionou bem, sem nenhuma alteração.

Avishekh Tewari
fonte
0

Eu enfrentei esse problema devido à versão do MySQL 8.0.11 revertendo para 5.7 resolvida para mim

Gautam Yadav
fonte
0

Eu tive o mesmo erro,

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

no meu caso, o WAR tinha application.properties dentro dele, que apontava para o servidor de desenvolvimento em
que application.properties externo apontava para o servidor DB correto.

verifique se você não possui outros aplicativos.properties no caminho de classe / jars ...

JavaSheriff
fonte