ChatGPT解决这个技术问题 Extra ChatGPT

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

我正在尝试运行一个通过 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");
         }
      };
   }
}

我在这里做错了什么?

如果需要多数据库支持,请参阅我在 stackoverflow.com/questions/72296481/… 处的解决方案。

M
M. Deinum

首先删除所有配置 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);
  }

}

假设您有一个带有 @EnableAutoConfigurationmain 方法的类,您不需要 @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 不,它不是......您可能首先想阅读属性是如何加载的,尤其是 Spring Boot 的支持,而不是随机评论。如果您直接设置文件权限,磁盘上的密码就不会成为问题。将它们放入数据库并没有好得多...
而不是使用 3 个注释,即 Configuration、EnableAutoConfiguration、ComponentScan。我们可以使用 SpringBootApplication 注解
m
mhnagaoka

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

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


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

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


这是一个很好的答案 - 允许我为我的数据库类使用 MockBean 并且在我的属性配置文件中没有真正的连接信息
将 spring.jpa.properties.hibernate.dialect 添加到 application.properties 对我有帮助。谢谢)
如果您对不同供应商的数据库使用多个数据源,这将不起作用。例如,如果您有一个用于 DB2 的数据源和另一个用于 Oracle 的数据源,这将不起作用。
A
ACV

未创建数据库时出现此错误。手动创建数据库后,它工作正常。


通常您可以使用“spring.jpa.hibernate.ddl-auto=create”来避免手动创建
@Andrei - 我将如何/在哪里指定“spring.jpa.hibernate.ddl-auto=create”?
@AlexWorden,Andrei 的意思是你可以把它放在 application.properties 如果它是 Spring Boot。必须有基于 xml 的 Spring 配置的等价物。
是否仅在数据库不存在或数据库中的表不存在时才会出现此错误?
我输入了错误的密码,我面临同样的错误。谢谢 ACV,你帮了我很多。
P
Pankaj

我也遇到了类似的问题。但是,这是由于提供的密码无效。另外,我想说您的代码似乎是使用 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=

E
Eric B.

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

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


谢谢你的评论让我检查了错误的连接端口
对我来说也是一样!
Y
Yogeshivu N

删除多余的休眠配置

如果您使用的是 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 对我有帮助。谢谢)
如果您对不同供应商的数据库使用多个数据源,这将不起作用。例如,如果您有一个用于 DB2 的数据源和另一个用于 Oracle 的数据源,这将不起作用。
A
Arthur Kazemi

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

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

将 spring.jpa.properties.hibernate.dialect 添加到 application.properties 对我有帮助。谢谢)
如果您对不同供应商的数据库使用多个数据源,这将不起作用。例如,如果您有一个用于 DB2 的数据源和另一个用于 Oracle 的数据源,这将不起作用。
Y
Yaroslav

在 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 像上面一样工作正常。谢谢回复。
a
abitcode

以下是导致 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:致命:数据库“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:致命:用户“postgres”的密码验证失败 spring.datasource.username= {DB USERNAME HERE} spring.datasource.password= {DB PASSWORD HERE}


u
user7169604

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


M
Michał

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

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

C
Chayne P. S.

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


z
zbig

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

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

o
obesechicken13

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


你能进一步详细说明吗?你这个答案是什么意思?
我只需要添加 mysql 依赖项。
d
doesnt_matter

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


我可以确认存在某种 Hibernate 问题,在连接失败时会报告此错误。我可以重现打开和关闭网络的问题。
K
Kannan Ramamoorthy

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


z
zygimantus

如果您使用此行:

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

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


A
Alejandro Teixeira Muñoz

相同,但在 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>

A
Ajitesh

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

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


我允许所有流量到 RDS Aurora MySQL 的安全组,这对我有用。如果您想更具体或针对 prod env,请仅添加允许的 ips
Y
Yamashiro Rion

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

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

J
JavaSheriff

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

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

J
Joel Mata

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

PS:我正在使用 MariaDB


V
Veli-Matti Sorvala

我在以下三种情况下重现了此错误消息:

不存在用户名写在 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 的情况下是否可以在这三种情况下重现此错误消息。


F
Farouk

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


M
Michael

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

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

L
Lahiru Gamage

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


a
ascripter

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


G
Gautam Yadav

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


A
Ahmed Ashour

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

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

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


关注公众号,不定期副业成功案例分享
关注公众号

不定期副业成功案例分享

领先一步获取最新的外包任务吗?

立即订阅