org.hibernate.HibernateException:如果未设置“ hibernate.dialect”,则对DialectResolutionInfo的访问不能为null


205

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

我在这里做错了什么?

Answers:


199

首先删除所有配置,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并且基本上是针对同一数据源的,则可以执行以下操作(尽管对于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的存储库)。

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

@SpringBootApplication
public class Application {

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

我还建议删除commons-dbcp依赖关系,因为这将允许Spring Boot配置更快,更可靠的HikariCP实现。


1
但是有什么办法可以避免创建此文件application.propertes?我更喜欢在HibernateConfig类中进行所有配置的方法。
Kleber Mota 2014年

2
为什么?Spring Boot的全部目的是为您完成自动配置...所以您更喜欢在属性文件中的7行中包含详细的Java配置?
M. Deinum 2014年

2
在属性文件中甚至可能是6行。使用Postgres时,无需设置spring.datasource.driverClassName,因为Boot将从spring.datasource.url推断出它。
2014年

2
@AlexWorden不,不是。。。您可能不想首先添加随机注释,而是首先要阅读如何加载属性,尤其是Spring Boot所具有的支持。如果直接设置文件权限,则磁盘上的密码不必成问题。将它们放在数据库中并没有更好...
M. Deinum 2015年

4
而不是使用3个注释,即Configuration,EnableAutoConfiguration,ComponentScan。我们可以使用SpringBootApplication注释
Pankaj,2015年

158

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

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


2
我的问题与此类似,因为服务器上的pg_hba.conf没有配置用于远程连接,这给了我这个错误。
布赖恩

8
如果您尝试连接的数据库不存在,您还会看到此错误。
乔纳斯·皮德森

12
遇到相同的问题,在我的情况下,数据库已启动,但凭据错误。+1
费德里科广场

令人惊讶的是,当删除的架构期望hbm2ddl.auto = true将创建数据库和表时,我开始遇到此问题。但是失败了。但是我创建了一个空的模式hbm2ddl却创建了表格
Saurabh

数据库计算机的IP已更改,但DNS解析为旧版本:-(
Illidan

24

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


这是一个很好的答案-允许我将MockBean用于我的数据库类,而在我的属性配置文件中没有真实的连接信息
Taylor

将spring.jpa.properties.hibernate.dialect添加到application.properties帮助了我。谢谢)
Maks

22

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


1
通常,您可以通过使用“ spring.jpa.hibernate.ddl-auto = create”来避免手动创建
Andrei 2016年

@Andrei-如何/在哪里指定“ spring.jpa.hibernate.ddl-auto = create”?
亚历克斯·沃登

2
@ AlexWorden,Andrei表示,如果它是Spring Boot,则可以将其放在application.properties中。对于基于xml的Spring配置必须具有等效项。
ACV

仅当数据库不存在或数据库中的表不存在时才出现此错误吗?
zygimantus

1
我输入了错误的密码,并且遇到了同样的错误。谢谢ACV,您对我有很大帮助。
桑图

17

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

8

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

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


谢谢您的评论,导致我检查了错误的连接端口
Feras

4

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


4

确保您application.properties拥有所有正确的信息:(我将数据库端口从更改88893306可以正常工作)

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

4

在jpa java config的春季启动中,您需要扩展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并正常工作。谢谢。
Fatih yavuz

4

删除冗余的休眠配置

如果您使用的是Spring Boot,则不需要显式提供JPA和Hibernate配置,因为Spring Boot可以为您提供服务。

添加数据库配置属性

application.propertiesSpring Boot配置文件中,您具有添加数据库配置属性:

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

添加休眠特定的属性

并且,在同一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帮助了我。谢谢)
Maks

3

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

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

将spring.jpa.properties.hibernate.dialect添加到application.properties帮助了我。谢谢)
Maks

2

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

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


2

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


1
我可以确认是否存在某种Hibernate问题,当它无法连接时会报告此错误。我可以重现打开和关闭网络的问题。
borjab


2

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

示例:在带有Postgres DB的Spring引导应用中

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

  • org.postgresql.util.PSQLException:到本地主机的连接:5432被拒绝。检查主机名和端口是否正确以及邮局主管正在接受TCP / IP连接。
  • java.net.ConnectException:连接被拒绝:connect
  • 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:到本地主机的连接:5431被拒绝。检查主机名和端口是否正确以及邮局主管正在接受TCP / IP连接。
  • java.net.ConnectException:连接被拒绝:connect

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

  • 正如@Pankaj提到的
  • org.postgresql.util.PSQLException:致命:用户“ postgres”的密码身份验证失败

    spring.datasource.username= {DB USERNAME HERE}

    spring.datasource.password= {DB PASSWORD HERE}


1

如果您使用此行:

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

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


1

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

1

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

我遇到了这个问题,上面做的事情为我解决了这个问题。


我允许所有流量流向RDS Aurora MySQL的安全组,这对我来说很成功。如果您想更具体或针对产品环境,请仅添加允许的ips
AleksandarT

1

我也有这个问题。在我的情况下,这是因为没有将任何拨款分配给MySQL用户。向我的应用使用的MySQL用户分配赠款解决了该问题:

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

1

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

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

1

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

  • 没有用户名写在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中有类似的命令,但是我没有测试过在这三种情况下是否可以重现此错误消息。


0

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


0

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

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

0

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


0

我遇到了同样的问题:我尝试连接的数据库不存在。我用过jpa.database=default(我想这意味着它将尝试连接到数据库,然后自动选择方言)。启动数据库后,它无需任何更改即可正常工作。





0

我有同样的错误,

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

在我的情况下,WAR的application.properties指向开发服务器
,外部application.properties指向正确的数据库服务器。

确保您在类路径/ jar中没有任何其他application.properties ...

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.