org.hibernate.HibernateException: доступ к DialectResolutionInfo не может быть нулевым, если не задано значение hibernate.dialect.

206

Я пытаюсь запустить приложение Spring-Boot, которое использует Hibernate через 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: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");
         }
      };
   }
}

что я тут не так делаю?

Клебер Мота
источник

Ответы:

201

Сначала удалите все ваши настройки Spring Boot запустит его для вас.

Убедитесь, что у вас есть application.propertiesclasspath и добавьте следующие свойства.

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

Если вам действительно нужен доступ к a, SessionFactoryи это в основном для того же источника данных, то вы можете сделать следующее (что также задокументировано здесь, хотя для XML, а не для JavaConfig).

@Configuration        
public class HibernateConfig {

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

Таким образом, у вас есть EntityManagerFactoryи a и a SessionFactory.

ОБНОВЛЕНИЕ: Начиная с Hibernate 5 SessionFactoryфактически расширяет EntityManagerFactory. Таким образом, чтобы получить a, 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
2
Зачем? Вся цель Spring Boot состоит в том, что он выполняет автоматическую настройку для вас ... Итак, вы предпочитаете включать подробную конфигурацию Java в 7 строк в файле свойств ?!
М. Дейнм
2
Это может быть даже 6 строк в файле свойств. Вам не нужно устанавливать spring.datasource.driverClassName, когда вы используете Postgres, так как Boot будет выводить его из spring.datasource.url.
Энди Уилкинсон
2
@AlexWorden Нет, это не так ... Вместо размещения случайных комментариев, вы можете сначала захотеть прочитать, как загружаются свойства, особенно поддержка Spring Boot. Пароли на диске не должны быть проблемой, если вы установите права на файл прямо. Поместить их в базу данных не намного лучше ...
М. Дейнм
4
Вместо того, чтобы использовать 3 аннотации, то есть Конфигурация, EnableAutoConfiguration, ComponentScan. Мы можем использовать аннотацию SpringBootApplication
Pankaj
159

Я столкнулся с аналогичной проблемой при запуске приложения (с использованием Spring Boot) с отключенным сервером базы данных .

Hibernate может определить правильный диалект для использования автоматически, но для этого ему нужно живое соединение с базой данных.

mhnagaoka
источник
2
Моя проблема была похожа на это в том, что файл pg_hba.conf на сервере не был настроен для удаленного подключения, что привело меня к этой ошибке.
Брайан
8
Если база данных, к которой вы пытаетесь подключиться, не существует, вы также видите эту ошибку.
Йонас Педерсен
12
Возникла та же проблема, в моем случае БД работала, но учетные данные были неверными. +1
Федерико Пьяцца
удивительно, я начал получать эту проблему, когда отброшенная схема, ожидая, что hbm2ddl.auto = true создаст БД и таблицы. Однако это не удалось. но вэнь я создала пустая схему hbm2ddl работал создание таблиц
Саурабй
IP машины базы данных была изменена , но DNS решала к старому :-(
Иллидан
24

добавить spring.jpa.properties.hibernate.dialect = org.hibernate.dialect.MySQLDialectв файл application.properties

высокогорный
источник
Это отличный ответ - позволяет мне использовать MockBean для моего класса базы данных и не иметь реальной информации о соединении в моем профиле свойств
Тейлор
Добавление spring.jpa.properties.hibernate.dialect в приложение. Свойства помогли мне. Спасибо)
Макс
22

Я получил эту ошибку, когда моя база данных не была создана. После создания БД вручную все работало нормально.

ACV
источник
1
Обычно вы можете избежать ручного создания, используя «spring.jpa.hibernate.ddl-auto = create»
Андрей
@Andrei - как / где бы я указал "spring.jpa.hibernate.ddl-auto = create"?
Алекс Уорден
2
@AlexWorden, Андрей имел в виду, что вы можете поместить его в application.properties, если это Spring Boot. Должен быть эквивалент для конфигурации Spring на основе xml.
ACV
Эта ошибка появляется только тогда, когда база данных не существует или также когда таблицы внутри базы данных отсутствуют?
Зигимантус
1
Я дал неправильный пароль, и я столкнулся с той же ошибкой. Спасибо, ACV, вы мне очень помогли.
Санту
17

Я также столкнулся с подобной проблемой. Но это произошло из-за предоставленного неверного пароля. Кроме того, я хотел бы сказать, что ваш код выглядит как код старого стиля с использованием Spring. Вы уже упоминали, что используете весеннюю загрузку, что означает, что большинство вещей будут автоматически настроены для вас. Диалект гибернации будет автоматически выбран на основе драйвера БД, доступного на пути к классам, вместе с действительными учетными данными, которые можно использовать для правильного тестирования соединения. Если есть какие-либо проблемы с подключением, вы снова столкнетесь с той же ошибкой. только 3 свойства необходимы в 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=
Панкай
источник
8

Я столкнулся с той же проблемой, и моя проблема заключалась в том, что БД, к которой я пытался подключиться, не существовала.

Я создал базу данных, проверил строку URL / соединения и перезапустил, и все заработало как положено.

Эрик Б.
источник
Спасибо, что ваш комментарий привел меня к проверке порта подключения, который был неправильным
Feras
4

это происходит потому, что ваш код не связывает базу данных. Убедитесь, что у вас есть mysql драйвер и имя пользователя, пароль правильный.

user7169604
источник
4

Убедитесь, что у вас application.propertiesесть вся правильная информация: (Я изменил мой порт БД с того, 8889чтобы 3306он работал)

 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, как описано выше, и работал нормально. Спасибо за ответ.
Фатих Явуз
4

Удалите избыточную конфигурацию Hibernate

Если вы используете Spring Boot, вам не нужно явно указывать конфигурацию JPA и Hibernate, поскольку Spring Boot может сделать это за вас.

Добавить свойства конфигурации базы данных

В application.propertiesфайле конфигурации Spring 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

Добавить 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 в приложение. Свойства помогли мне. Спасибо)
Макс
3

У меня была такая же проблема. добавление этого в application.properties решило проблему:

spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQLDialect
Артур Каземи
источник
Добавление spring.jpa.properties.hibernate.dialect в приложение. Свойства помогли мне. Спасибо)
Макс
2

В моем случае пользователь не может подключиться к базе данных. Если возникнет та же проблема, если журнал содержит предупреждение перед исключением:

WARN HHH000342: Could not obtain connection to query metadata : Login failed for user 'my_user'.
Збигнев
источник
2

Убедитесь, что у вас в базе есть база данных, как у OP. Это была моя проблема.

obesechicken13
источник
Можете ли вы уточнить дальше? Что вы имеете в виду под этим ответом?
Тунаки
Мне просто нужно добавить зависимость MySQL.
obesechicken13
2

Моя проблема заключалась в том, что встроенная база данных уже была подключена. тесная связь

doesnt_matter
источник
1
Я могу подтвердить, что существует какая-то проблема Hibernate, которая сообщает об этой ошибке, когда не удается подключиться. Я мог воспроизвести проблему включения и выключения сети.
Борхаб
2

Я получил эту проблему, когда Eclipse не смог найти драйвер JDBC. Пришлось сделать обновление Gradle от затмения, чтобы получить эту работу.

Каннан Рамамурти
источник
2

Ниже приведены некоторые из причин hibernate.dialectнеустановленной проблемы. Большинство из этих исключений отображаются в журнале запуска, за которым, наконец, следует упомянутая проблема.

Пример: загрузочное приложение Spring с Postgres DB

1. Проверьте, установлена ​​ли база данных и запущен ли ее сервер.

  • org.postgresql.util.PSQLException: Соединение с localhost: 5432 отказано. Убедитесь, что имя хоста и порт указаны правильно и что администратор почты принимает соединения 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 отказано. Убедитесь, что имя хоста и порт указаны правильно и что администратор почты принимает соединения 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}

abitcode
источник
1

Если вы используете эту строку:

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

убедитесь, что env.getProperty("hibernate.dialect")это не ноль.

zygimantus
источник
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, это может произойти, если вы не можете подключиться к базе данных. Перейдите к настройке групп безопасности AWS для MySQL RDS и измените правило входящих IP-адресов, обновив MyIP.

Я столкнулся с этой проблемой, и выполнение выше помогло мне решить проблему.

Ajitesh
источник
Я разрешил весь трафик группе безопасности RDS Aurora MySQL, и это помогло мне. Если вы хотите быть более конкретным или для env prod, добавьте только разрешенные 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
JavaSheriff
источник
1

Я воспроизвел это сообщение об ошибке в следующих трех случаях:

  • Не существует пользователя базы данных с именем пользователя, записанным в файле application.properties или файле persistence.properties или, как в вашем случае, в файле HibernateConfig
  • В развернутой базе данных есть этот пользователь, но пользователь идентифицируется по паролю, отличному от того, который указан в одном из вышеуказанных файлов
  • В базе данных есть этот пользователь и совпадают пароли, но у этого пользователя нет всех прав, необходимых для выполнения всех задач базы данных, которые выполняет ваше приложение весенней загрузки

Очевидное решение состоит в том, чтобы создать нового пользователя базы данных с тем же именем пользователя и паролем, что и в приложении весенней загрузки, или изменить имя пользователя и пароль в файлах приложения весенней загрузки, чтобы соответствовать существующему пользователю базы данных и предоставить достаточные привилегии этому пользователю базы данных. В случае базы данных 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.

Вели-Матти Сорвала
источник
0

У меня была та же самая проблема, и это было вызвано неспособностью соединиться с экземпляром базы данных. Ищите ошибку hibernate HHH000342 в журнале над этой ошибкой, она должна дать вам представление о том, где происходит сбой соединения с БД (неверное имя пользователя / пароль, URL и т. Д.)

Фарук
источник
0

Это случилось со мной, потому что я не добавил conf.configure();до начала сессии:

Configuration conf = new Configuration();
conf.configure();
Диана
источник
0

Убедитесь, что вы ввели правильные данные в application.properties и укажите, доступен ли ваш сервер базы данных. Например, когда вы подключаетесь к MySQL, проверьте, правильно ли работает XAMPP .

Лахиру Гамаж
источник
0

Я столкнулся с той же проблемой: база данных, которую я пытался подключить, не существовала. Я использовал jpa.database=default(что, я думаю, означает, что он будет пытаться подключиться к базе данных, а затем автоматически выбрать диалект). Как только я запустил базу данных, она работала нормально без каких-либо изменений.

Авишех Тевари
источник
0

Я столкнулся с этой проблемой из-за версии Mysql 8.0.11, возвращающейся к 5.7, решенной для меня

Гаутам Ядав
источник
0

У меня была такая же ошибка,

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

в моем случае WAR имел внутри application.properties, который указывал на сервер разработки,
где external application.properties указывал на нужный сервер БД.

убедитесь, что у вас нет других application.properties в classpath / jars ...

JavaSheriff
источник