org.hibernate.HibernateException:当未设置“hibernate.dialect”时,对 DialectResolutionInfo 的访问不能为空

Posted

技术标签:

【中文标题】org.hibernate.HibernateException:当未设置“hibernate.dialect”时,对 DialectResolutionInfo 的访问不能为空【英文标题】:org.hibernate.HibernateException: Access to DialectResolutionInfo cannot be null when 'hibernate.dialect' not set 【发布时间】:2015-01-23 04:02:26 【问题描述】:

我正在尝试通过 spring-jpa 运行使用休眠的 spring-boot 应用程序,但我收到此错误:

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

我的 pom.xml 文件是这样的:

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

我的休眠配置是这样的(方言配置在这个类的最后一个方法中):

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

我在这里做错了什么?

【问题讨论】:

【参考方案1】:

首先删除所有配置 Spring Boot 将为您启动它。

确保您的类路径中有 application.properties 并添加以下属性。

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

如果您确实需要访问 SessionFactory 并且基本上是针对同一个数据源,那么您可以执行以下操作(这也记录在 here 尽管用于 XML,而不是 JavaConfig)。

@Configuration        
public class HibernateConfig 

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

这样你就有了EntityManagerFactorySessionFactory

更新:从 Hibernate 5 开始,SessionFactory 实际上扩展了 EntityManagerFactory。因此,要获得SessionFactory,您可以简单地将EntityManagerFactory 转换为它或使用unwrap 方法来获得一个。

public class SomeHibernateRepository 

  @PersistenceUnit
  private EntityManagerFactory emf;

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


假设您有一个带有 main 方法和 @EnableAutoConfiguration 的类,您不需要 @EnableTransactionManagement 注释,因为 Spring Boot 将为您启用。 com.spring.app 包中的一个基本应用程序类就足够了。

@Configuration
@EnableAutoConfiguration
@ComponentScan
public class Application 


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

 

这样的事情应该足以检测到您的所有类(包括实体和基于 Spring Data 的存储库)。

更新:在更新的 Spring Boot 版本中,这些注释可以替换为单个 @SpringBootApplication

@SpringBootApplication
public class Application 

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

我还建议删除 commons-dbcp 依赖项,因为这将允许 Spring Boot 配置更快、更健壮的 HikariCP 实现。

【讨论】:

但是有没有办法避免创建这个文件application.propertes?我更喜欢在 HibernateConfig 类中进行所有配置的方式。 为什么? Spring Boot 的全部目的是为您进行自动配置......所以您更喜欢在属性文件中包含超过 7 行的详细 java 配置?! 属性文件中甚至可以是 6 行。使用 Postgres 时不需要设置 spring.datasource.driverClassName,因为 Boot 会从 spring.datasource.url 推断出来。 @AlexWorden 不,它不是...与其放置随机 cmets,您可能首先想阅读属性是如何加载的,尤其是 Spring Boot 的支持。如果您直接设置文件权限,磁盘上的密码就不会成为问题。将它们放入数据库也好不到哪里去…… 而不是使用 3 个注解,即 Configuration、EnableAutoConfiguration、ComponentScan。我们可以使用 SpringBootApplication 注解【参考方案2】:

我在启动应用程序(使用 Spring Boot)时遇到了类似的问题数据库服务器关闭

Hibernate 可以自动确定要使用的正确方言,但为了做到这一点,它需要与数据库的实时连接。

【讨论】:

我的问题与此类似,因为服务器上的 pg_hba.conf 没有为远程连接配置,这给了我这个错误。 如果您尝试连接的数据库不存在,您也会看到此错误。 遇到了同样的问题,在我的情况下,数据库已启动,但凭据错误。 +1 令人惊讶的是,当删除期望 hbm2ddl.auto=true 的架构将创建数据库和表时,我开始遇到此问题。但是它失败了。但是我创建了空模式 hbm2ddl 工作创建表 对我来说,数据库服务器也没有启动,这就是为什么在部署 spring boot 应用程序时出现此错误。【参考方案3】:

在 application.properties 文件中添加spring.jpa.properties.hibernate.dialect = org.hibernate.dialect.mysqlDialect

【讨论】:

这是一个很好的答案 - 允许我将 MockBean 用于我的数据库类,并且在我的属性配置文件中没有真正的连接信息 将 spring.jpa.properties.hibernate.dialect 添加到 application.properties 对我有帮助。谢谢)【参考方案4】:

我在未创建数据库时收到此错误。手动创建数据库后,效果很好。

【讨论】:

通常您可以通过使用“spring.jpa.hibernate.ddl-auto=create”来避免手动创建 @Andrei - 我将如何/在哪里指定“spring.jpa.hibernate.ddl-auto=create”? @AlexWorden,Andrei 的意思是如果它是 Spring Boot,你可以将它放在 application.properties 中。基于 xml 的 Spring 配置必须有等价物。 这个错误是只在数据库不存在的时候出现,还是在数据库里面的表不存在的时候出现? 我输入了错误的密码,我遇到了同样的错误。谢谢 ACV,你帮了我很多。【参考方案5】:

我也遇到了类似的问题。但是,这是由于提供的密码无效。另外,我想说您的代码似乎是使用 spring 的旧式代码。您已经提到您正在使用 Spring Boot,这意味着大部分内容将为您自动配置。休眠方言将根据类路径上可用的数据库驱动程序以及可用于正确测试连接的有效凭据自动选择。如果连接有任何问题,您将再次面临同样的错误。 application.properties 中只需要 3 个属性

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

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

【讨论】:

【参考方案6】:

我遇到了同样的问题,我的问题是我尝试连接的数据库不存在。

我创建了数据库,验证了 URL/连接字符串并重新运行,一切都按预期工作。

【讨论】:

谢谢你的评论让我检查了错误的连接端口 对我来说也一样!【参考方案7】:

删除多余的休眠配置

如果您使用的是 Spring Boot,则无需显式提供 JPA 和 Hibernate 配置,因为 Spring Boot 可以为您完成。

添加数据库配置属性

application.properties Spring Boot 配置文件中,您可以添加数据库配置属性:

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

添加 Hibernate 特定属性

而且,在同一个application.properties 配置文件中,您还可以设置自定义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

就是这样!

【讨论】:

将 spring.jpa.properties.hibernate.dialect 添加到 application.properties 对我有帮助。谢谢)【参考方案8】:

我有同样的问题。将此添加到 application.properties 解决了这个问题:

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

【讨论】:

将 spring.jpa.properties.hibernate.dialect 添加到 application.properties 对我有帮助。谢谢)【参考方案9】:

在 jpa java config 的 spring boot 中,您需要扩展 JpaBaseConfiguration 并实现它的抽象方法。

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


【讨论】:

某些情况下 application.properties 看不到属性的变化。我像上面一样添加了 properties.put 并且工作正常。谢谢回复。【参考方案10】:

发生这种情况是因为您的代码无法连接数据库。确保您有 mysql 驱动程序和用户名,密码正确。

【讨论】:

【参考方案11】:

确保您的application.properties 包含所有正确的信息:(我将我的数据库端口从8889 更改为3306 它有效)

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

【讨论】:

【参考方案12】:

以下是hibernate.dialect 未设置问题的一些原因。 大多数这些异常都显示在启动日志中,最后是提到的问题。

示例:在带有 Postgres DB 的 Spring Boot 应用程序中

1.检查数据库是否实际安装并启动其服务器。

org.postgresql.util.PSQLException:连接到 localhost:5432 被拒绝。检查主机名和端口是否正确,以及 postmaster 是否接受 TCP/IP 连接。 java.net.ConnectException:连接被拒绝:连接 org.hibernate.service.spi.ServiceException:无法创建请求的服务 [org.hibernate.engine.jdbc.env.spi.JdbcEnvironment]

2。检查数据库名称是否正确。

org.postgresql.util.PSQLException: FATAL: 数据库“foo”不存在

application.properties 文件中,

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

foo 不存在。 所以我从 pgAdmin 为 postgres 创建了数据库

CREATE DATABASE foo;

3。检查主机名和服务器端口是否可访问。

org.postgresql.util.PSQLException:连接到 localhost:5431 被拒绝。检查主机名和端口是否正确,以及 postmaster 是否接受 TCP/IP 连接。 java.net.ConnectException:连接被拒绝:连接

4。检查数据库凭据是否正确。

@Pankaj 提到

org.postgresql.util.PSQLException: FATAL: 用户“postgres”的密码验证失败

spring.datasource.username= DB USERNAME HERE

spring.datasource.password= DB PASSWORD HERE

【讨论】:

【参考方案13】:

在我的情况下,用户无法连接到数据库。如果日志在异常之前包含警告,则会有同样的问题:

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

【讨论】:

【参考方案14】:

确保你的 pom 中有你的数据库,就像 OP 一样。那是我的问题。

【讨论】:

您能详细说明一下吗?你这个答案是什么意思? 我只需要添加mysql依赖。【参考方案15】:

我的问题是嵌入式数据库已经连接。关闭连接

【讨论】:

我可以确认存在某种 Hibernate 问题,在连接失败时会报告此错误。我可以重现打开和关闭网络的问题。【参考方案16】:

当 Eclipse 无法找到 JDBC 驱动程序时,我遇到了这个问题。必须从 Eclipse 进行 gradle 刷新才能完成这项工作。

【讨论】:

【参考方案17】:

如果您使用此行:

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

确保env.getProperty("hibernate.dialect") 不为空。

【讨论】:

【参考方案18】:

相同,但在 JBoss WildFly AS 中。

解决了我的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>

【讨论】:

【参考方案19】:

对于那些使用 AWS MySQL RDS 的人,当您无法连接到数据库时可能会发生这种情况。转到 MySQL RDS 的 AWS 安全组设置,然后通过刷新 MyIP 来编辑入站 IP 规则。

我遇到了这个问题,上面的操作为我解决了这个问题。

【讨论】:

我允许所有流量到 RDS Aurora MySQL 的安全组,这对我有用。如果您想更具体或针对 prod env,请仅添加允许的 ips【参考方案20】:

我也有这个问题。就我而言,这是因为没有为 MySQL 用户分配任何授权。将授权分配给我的应用使用的 MySQL 用户解决了该问题:

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

【讨论】:

【参考方案21】:

我遇到了同样的问题,调试后发现 Spring application.properties 的数据库服务器 IP 地址错误

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

【讨论】:

【参考方案22】:

spring.jpa.database-platform=org.hibernate.dialect.MariaDB53Dialect 添加到我的属性文件对我有用。

PS:我正在使用 MariaDB

【讨论】:

【参考方案23】:

我在以下三种情况下重现了这个错误信息:

不存在用户名写在 application.properties 文件或 persistence.properties 文件中的数据库用户,或者在您的情况下,在 HibernateConfig 文件中 部署的数据库有该用户,但用户的密码与上述文件之一不同 数据库的用户和密码匹配,但该用户不具备完成 spring-boot 应用程序执行的所有数据库任务所需的所有权限

显而易见的解决方案是使用与 spring-boot 应用程序中相同的用户名和密码创建新的数据库用户,或者更改 spring-boot 应用程序文件中的用户名和密码以匹配现有数据库用户并授予该数据库足够的权限用户。在 MySQL 数据库的情况下,可以如下所示完成:

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

显然在 Postgresql 中也有类似的命令,但我没有测试在 Postgresql 的情况下是否可以在这三种情况下重现此错误消息。

【讨论】:

【参考方案24】:

事实证明,如果您使用 Spring JPA,application.properties 文件中没有人提到 set spring.jpa.database=mysql。这是对我来说最简单的答案,我想分享这个问题。

【讨论】:

【参考方案25】:

我遇到了同样的问题,这是由于无法连接到数据库实例造成的。在该错误上方的日志中查找休眠错误 HHH000342,它应该让您了解数据库连接失败的位置(不正确的用户名/密码、url 等)

【讨论】:

【参考方案26】:

这发生在我身上,因为我在开始会话之前没有添加conf.configure();

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

【讨论】:

【参考方案27】:

确保您在 application.properties 中输入了有效的详细信息以及您的数据库服务器是否可用。例如,当您连接 MySQL 时,请检查 XAMPP 是否正常运行。

【讨论】:

【参考方案28】:

我遇到了同样的问题:我尝试连接的数据库不存在。我使用了jpa.database=default(我猜这意味着它会尝试连接到数据库,然后自动选择方言)。一旦我启动数据库,它就可以正常工作,没有任何变化。

【讨论】:

【参考方案29】:

由于 Mysql 8.0.11 版本恢复到 5.7 为我解决了这个问题

【讨论】:

【参考方案30】:

使用休眠代码生成后我遇到了同样的错误

https://www.mkyong.com/hibernate/how-to-generate-code-with-hibernate-tools/

然后hibernate.cfg.xml/src/main/java 中创建 但没有连接参数 删除后 - 我的问题解决了

【讨论】:

以上是关于org.hibernate.HibernateException:当未设置“hibernate.dialect”时,对 DialectResolutionInfo 的访问不能为空的主要内容,如果未能解决你的问题,请参考以下文章