我试图通过spring-jpa运行一个使用hibernate的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>

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

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

我哪里做错了?


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

确保你有申请。属性,并添加以下属性。

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

这样你就有了一个EntityManagerFactory和一个SessionFactory。

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

public class SomeHibernateRepository {

  @PersistenceUnit
  private EntityManagerFactory emf;

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

}

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

@Configuration
@EnableAutoConfiguration
@ComponentScan
public class Application {


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

} 

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

更新:在SpringBoot的最新版本中,这些注释可以用一个@SpringBootApplication代替。

@SpringBootApplication
public class Application {

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

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

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

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

我得到这个错误时,我的数据库没有创建。在手动创建DB之后,它工作得很好。

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

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

I also faced a similar issue. But, it was due to the invalid password provided. Also, I would like to say your code seems to be old-style code using spring. You already mentioned that you are using spring boot, which means most of the things will be auto configured for you. hibernate dialect will be auto selected based on the DB driver available on the classpath along with valid credentials which can be used to test the connection properly. If there is any issue with the connection you will again face the same error. only 3 properties needed in 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=

确保你的申请。properties有所有正确的信息:(我改变了我的db端口从8889到3306,它工作)

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

在我的例子中,用户无法连接到数据库。如果日志在异常之前包含警告,If也会有同样的问题:

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

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

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

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

我也遇到了同样的问题,这是由于无法连接到数据库实例造成的。在日志中寻找hibernate错误HHH000342,它应该会让你知道db连接失败的位置(错误的用户名/pass, url等)。

在应用程序中添加spring.jpa.properties.hibernate.dialect = org.hibernate.dialect.MySQLDialect。属性文件

如果你正在使用这条线路:

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

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

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

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

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

我遇到了同样的问题:我试图连接的数据库不存在。我使用jpa。database=default(我猜这意味着它将尝试连接到数据库,然后自动选择方言)。一旦我启动数据库,它工作得很好,没有任何改变。

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

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

我遇到了这个问题,上面的方法帮我解决了这个问题。

在使用hibernate代码生成后,我遇到了同样的错误

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

然后在/src/main/java目录下创建hibernate.cfg.xml 但是没有连接参数 移除后,我的问题就解决了

我遇到这个问题,因为Mysql 8.0.11版本恢复到5.7为我解决了

当Eclipse无法找到JDBC驱动程序时,我遇到了这个问题。不得不做一个gradle刷新从eclipse得到这个工作。

在jpa java配置的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");
    }

}

我也有这个问题。在我的情况下,这是因为没有授权被分配给MySQL用户。分配授予MySQL用户,我的应用程序使用解决了这个问题:

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

如果日志中的上述错误是这样的:" error - HikariPool-1 - jdbcUrl is required with driverClassName" 那么解决方案是将“url”重写为“jdbc-url”,如下所示: 数据库应用程序。yml用于Spring从applications.properties启动

我也遇到了同样的问题,调试后发现是Spring应用程序。DB服务器的IP地址错误

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

我也犯了同样的错误,

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

在我的情况下,战争有应用。指向开发服务器的属性 其中外部应用。属性指向正确的DB服务器。

确保你没有其他的应用程序。类路径/ jars…

以下是休眠的一些原因。方言不设问题。 大多数这些异常都显示在启动日志中,最终会出现上述问题。

示例:在Spring引导应用程序中使用Postgres DB

1. 检查数据库是否已经安装,数据库服务器是否已经启动。

org.postgresql.util.PSQLException: Connection to localhost:5432 refused。检查主机名和端口是否正确,以及邮政管理员是否接受TCP/IP连接。 connectexception:连接拒绝:连接 org.hibernate.service.spi.ServiceException:无法创建请求的服务[org.hibernate.engine.jdbc.env.spi.JdbcEnvironment]

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

org.postgresql.util.PSQLException: FATAL:数据库“foo”不存在 在应用程序中。属性文件, Spring.datasource.url = jdbc:postgresql://localhost:5432/foo 但是foo并不存在。 因此,我从pgAdmin为postgres创建了数据库 创建数据库foo

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

org.postgresql.util.PSQLException: Connection to localhost:5431 refused。检查主机名和端口是否正确,以及邮政管理员是否接受TCP/IP连接。 connectexception:连接拒绝:连接

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

正如@Pankaj提到的 org.postgresql.util.PSQLException: FATAL: password authentication failed for user "postgres" spring.datasource。用户名={此处为数据库用户名} spring.datasource。密码={数据库密码}

在属性文件中添加spring.jpa.database-platform=org.hibernate.dialect.MariaDB53Dialect对我来说是有效的。

PS:我正在使用MariaDB

我也有同样的问题。将其添加到应用程序中。Properties解决了这个问题:

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

删除冗余的Hibernate配置

如果您正在使用Spring Boot,则不需要显式地提供JPA和Hibernate配置,因为Spring Boot可以为您提供这些配置。

添加数据库配置属性

在应用程序中。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特定的属性

在同一个应用程序中。属性配置文件,你也可以设置自定义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

就是这样!

我在以下三种情况下复制了此错误消息:

应用程序中不存在用户名的数据库用户。属性文件或持久性。属性文件,或者在hibernate econfig文件中 部署的数据库拥有该用户,但用户的密码与上述文件中的密码不同 数据库具有该用户和密码匹配,但该用户不具有完成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中,这个错误消息是否可以在这三种情况下重现。

在我的例子中,这个异常的根本原因来自于使用旧版本的mysql连接器,我有这个错误:

无法加载验证插件“caching_sha2_password”。mysql

将这一行添加到mysql服务器配置文件(my.cnf或my.ini)可以修复这个问题:

default_authentication_plugin = mysql_native_password

结果在应用程序中没有人提到set spring.jpa.database=mysql。属性文件,如果您使用Spring JPA。这是对我来说最简单的答案,我想在这个问题上分享。

作为一个更描述性的答案


修复连接数据库相关的问题:

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:100) ~[hibernate-core-5.4.8.Final.jar:5.4.8.Final]
    at org.hibernate.engine.jdbc.dialect.internal.DialectFactoryImpl.buildDialect(DialectFactoryImpl.java:54) ~[hibernate-core-5.4.8.Final.jar:5.4.8.Final]
    at org.hibernate.engine.jdbc.env.internal.JdbcEnvironmentInitiator.initiateService(JdbcEnvironmentInitiator.java:137) ~[hibernate-core-5.4.8.Final.jar:5.4.8.Final]
    at org.hibernate.engine.jdbc.env.internal.JdbcEnvironmentInitiator.initiateService(JdbcEnvironmentInitiator.java:35) ~[hibernate-core-5.4.8.Final.jar:5.4.8.Final]
    at org.hibernate.boot.registry.internal.StandardServiceRegistryImpl.initiateService(StandardServiceRegistryImpl.java:101) ~[hibernate-core-5.4.8.Final.jar:5.4.8.Final]
    at org.hibernate.service.internal.AbstractServiceRegistryImpl.createService(AbstractServiceRegistryImpl.java:263) ~[hibernate-core-5.4.8.Final.jar:5.4.8.Final]
    ... 38 common frames omitted

你需要做的是:

要选择与所需数据库(您在应用程序中使用的数据库)相关的特定数据源配置选项。属性文件),例如:spring.datasource.platform=postgres:

为了避免在连接时提示“FATAL: database "testDb" does not exist”:

使用PgAdmin需要手动创建数据库(如果您使用的是PostgreSQL开发平台):

基于应用程序内部的属性。属性文件:

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

配置剩余设置:

spring.datasource.url = jdbc: postgresql: / / localhost: 5432 / testDb spring.datasource.username = postgres spring.datasource.password = your_password

根据你的应用。属性文件:

点击“测试连接”和“应用”。

对我来说,解决问题的方法如下:

右键单击“持久化上的实体”窗口并选择相关数据源

检查代码(HibernateJpaVendorAdapter && JdbcEnvironmentInitiator),回退如下所示:

如果spring.jpa.properties.hibernate.temp.use_jdbc_metadata_defaults为true,则从db中获得方言。 否则,如果设置了spring.jpa.database-platform,则从那里获取方言 否则,如果设置了spring.jpa.database,则获得映射到HibernateJpaVendorAdapter中的默认硬文档方言

我通过添加hibernate.cfg.xml解决了这个问题:

<property name="dialect">org.hibernate.dialect.MySQL5Dialect</property>

当然,我在一个非常旧的应用程序上升级了Spring和Hibernate,并没有将其重构为新的标准,因此对大多数人来说,这个解决方案是无关紧要的,因为它只适用于以旧方式配置的应用程序。