org.hibernate.HibernateException: Dostęp do DialectResolutionInfo nie może być zerowy, gdy nie ustawiono parametru „hibernacja.dialect”

205

Próbuję uruchomić aplikację Spring-Boot, która używa hibernacji za pośrednictwem Spring-JPA, ale otrzymuję ten błąd:

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

mój plik pom.xml to:

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

moja konfiguracja hibernacji jest taka (konfiguracja dialektu jest w ostatniej metodzie z tej klasy):

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

co tutaj robię źle?

Kleber Mota
źródło

Odpowiedzi:

199

Najpierw usuń całą konfigurację. Uruchomi ją Spring Boot.

Upewnij się, że masz application.propertiesścieżkę klasy i dodaj następujące właściwości.

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

Jeśli naprawdę potrzebujesz dostępu do SessionFactorya, który jest zasadniczo dla tego samego źródła danych, możesz wykonać następujące czynności (które są tutaj również udokumentowane , chociaż dla XML, a nie JavaConfig).

@Configuration        
public class HibernateConfig {

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

W ten sposób masz zarówno an EntityManagerFactoryi a SessionFactory.

AKTUALIZACJA: Od Hibernacji 5 SessionFactoryfaktycznie rozszerza EntityManagerFactory. Aby uzyskać SessionFactory, możesz po prostu rzucić na EntityManagerFactoryniego lub użyć unwrapmetody, aby go zdobyć.

public class SomeHibernateRepository {

  @PersistenceUnit
  private EntityManagerFactory emf;

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

}

Zakładając, że masz klasę z mainmetodą, @EnableAutoConfigurationktórej nie potrzebujesz, @EnableTransactionManagementadnotacja zostanie włączona przez Spring Boot. Podstawowa klasa aplikacji w com.spring.apppakiecie powinna wystarczyć.

@Configuration
@EnableAutoConfiguration
@ComponentScan
public class Application {


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

} 

Coś takiego powinno wystarczyć do wykrycia wszystkich twoich klas (w tym encji i repozytoriów opartych na Spring Data).

AKTUALIZACJA: Te adnotacje można zastąpić jednym @SpringBootApplicationw nowszych wersjach Spring Boot.

@SpringBootApplication
public class Application {

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

Sugeruję również usunięcie commons-dbcpzależności, ponieważ pozwoli to Spring Boot skonfigurować szybszą i bardziej niezawodną HikariCPimplementację.

M. Deinum
źródło
1
ale czy jest jakiś sposób, aby uniknąć utworzenia tego pliku application.propertes? Wolę sposób, w jaki wykonuję całą konfigurację w klasie HibernateConfig.
Kleber Mota
2
Czemu? Głównym celem Spring Boot jest to, że wykonuje on automatyczną konfigurację ... Więc wolisz zawrzeć pełną konfigurację Java w 7 wierszach w pliku właściwości ?!
M. Deinum
2
Może to być nawet 6 wierszy w pliku właściwości. Nie musisz ustawiać spring.datasource.driverClassName, gdy używasz Postgres, ponieważ Boot wywnioskuje to z spring.datasource.url.
Andy Wilkinson
2
@AlexWorden Nie, to nie jest ... Zamiast umieszczać losowe komentarze, możesz najpierw przeczytać, w jaki sposób właściwości są ładowane, zwłaszcza wsparcie Spring Boot. Hasła na dysku nie muszą stanowić problemu, jeśli ustawisz prawa do plików prosto. Umieszczenie ich w bazie danych nie jest dużo lepsze ...
M. Deinum,
4
Zamiast używać 3 adnotacji, tj. Configuration, EnableAutoConfiguration, ComponentScan. Możemy użyć adnotacji SpringBootApplication
Pankaj
158

Miałem podobny problem podczas uruchamiania aplikacji (przy użyciu Spring Boot) przy wyłączonym serwerze bazy danych .

Hibernacja może określić właściwy dialekt do użycia automatycznie, ale w tym celu potrzebuje połączenia z bazą danych na żywo.

mhnagaoka
źródło
2
Mój problem był podobny do tego, że pg_hba.conf na serwerze nie został skonfigurowany do połączenia zdalnego, co dało mi ten błąd.
Brian,
8
Jeśli baza danych, z którą próbujesz się połączyć, nie istnieje, zobaczysz również ten błąd.
Jonas Pedersen
12
Mam ten sam problem, w moim przypadku baza danych nie działała, ale dane logowania były nieprawidłowe. +1
Federico Piazza,
nieoczekiwanie zacząłem dostawać ten problem, gdy upuszczony schemat oczekując, że hbm2ddl.auto = true utworzy bazę danych i tabele. jednak się nie udało. ale wen utworzyłem pusty schemat hbm2ddl pracował przy tworzeniu tabel
Saurabh
Adres IP maszyny bazy danych został zmieniony, ale DNS został rozwiązany na stary :-(
Illidan
24

dodaj spring.jpa.properties.hibernate.dialect = org.hibernate.dialect.MySQLDialectw pliku application.properties

alpejski
źródło
To świetna odpowiedź - pozwala mi użyć MockBean dla mojej klasy bazy danych i nie mieć rzeczywistych informacji o połączeniu w moim profilu właściwości
Taylor
Pomogło mi dodanie pliku spring.jpa.properties.hibernate.dialect do application.properties. Dziękuję)
Maks
22

Wystąpił ten błąd, gdy moja baza danych nie została utworzona. Po ręcznym utworzeniu DB działało dobrze.

ACV
źródło
1
Zwykle można uniknąć ręcznego tworzenia, używając „spring.jpa.hibernate.ddl-auto = create”
Andrei
@Andrei - jak / gdzie mam podać „spring.jpa.hibernate.ddl-auto = create”?
Alex Worden,
2
@AlexWorden, Andrei oznaczał, że możesz umieścić go w application.properties, jeśli jest to Spring Boot. Musi istnieć odpowiednik konfiguracji Spring opartej na XML.
ACV,
Czy ten błąd pojawia się tylko wtedy, gdy baza danych nie istnieje, czy też gdy tabele w bazie danych nie istnieją?
zygimantus,
1
Podałem nieprawidłowe hasło i napotkałem ten sam błąd. Dziękuję ACV, bardzo mi pomogłeś.
santu
17

Napotkałem również podobny problem. Ale było to spowodowane podanym nieprawidłowym hasłem. Chciałbym również powiedzieć, że twój kod wydaje się być kodem w starym stylu, używając wiosny. Wspomniałeś już, że używasz wiosennego rozruchu, co oznacza, że ​​większość rzeczy zostanie dla Ciebie automatycznie skonfigurowana. hibernacja zostanie automatycznie wybrana na podstawie sterownika DB dostępnego w ścieżce klasy wraz z prawidłowymi poświadczeniami, których można użyć do prawidłowego przetestowania połączenia. W przypadku problemów z połączeniem ponownie napotkasz ten sam błąd. potrzebne są tylko 3 właściwości w 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=
Pankaj
źródło
8

Natrafiłem na ten sam problem, a moim problemem było to, że baza danych, z którą próbowałem się połączyć, nie istniała.

Utworzyłem DB, zweryfikowałem adres URL / ciąg połączenia i przestawiłem ponownie i wszystko działało zgodnie z oczekiwaniami.

Eric B.
źródło
Dziękuję, że skomentowałeś, że sprawdziłem port połączenia, który był zły
Feras
4

dzieje się tak, ponieważ Twój kod nie łączy się z bazą danych. Upewnij się, że masz sterownik mysql i nazwę użytkownika, poprawne hasło.

użytkownik7169604
źródło
4

Upewnij się, że masz application.propertieswszystkie poprawne informacje: (Zmieniłem mój port db z 8889na 3306to działało)

 db.url: jdbc:mysql://localhost:3306/test
Vikram S.
źródło
4

W wiosennym rozruchu dla konfiguracji jpa java musisz rozszerzyć JpaBaseConfiguration i zaimplementować jej abstrakcyjne metody.

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

}
Jarosław
źródło
w niektórych przypadkach application.properties nie widzi zmian właściwości. I dodałem properties.put jak wyżej i działało dobrze.Txx za odpowiedź.
fatih yavuz
4

Usuń zbędną konfigurację hibernacji

Jeśli używasz Spring Boot, nie musisz jawnie podawać konfiguracji JPA i Hibernacji, ponieważ Spring Boot może to zrobić za Ciebie.

Dodaj właściwości konfiguracyjne bazy danych

W application.propertiespliku konfiguracyjnym Spring Boot dodano właściwości konfiguracji bazy danych:

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

Dodaj właściwości hibernacji

I w tym samym application.propertiespliku konfiguracyjnym możesz również ustawić niestandardowe właściwości Hibernacji:

# 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

Otóż ​​to!

Vlad Mihalcea
źródło
Pomogło mi dodanie pliku spring.jpa.properties.hibernate.dialect do application.properties. Dziękuję)
Maks
3

Miałem ten sam problem. dodanie tego do application.properties rozwiązało problem:

spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQLDialect
Arthur Kazemi
źródło
Pomogło mi dodanie pliku spring.jpa.properties.hibernate.dialect do application.properties. Dziękuję)
Maks
2

W moim przypadku użytkownik nie mógł połączyć się z bazą danych. Jeśli będzie miał ten sam problem, jeśli dziennik zawiera ostrzeżenie tuż przed wyjątkiem:

WARN HHH000342: Could not obtain connection to query metadata : Login failed for user 'my_user'.
zbig
źródło
2

Upewnij się, że masz swoją bazę danych w pom, tak jak OP. To był mój problem.

obesechicken13
źródło
Czy możesz dalej opracowywać? Co masz na myśli z tą odpowiedzią?
Tunaki
Musiałem tylko dodać zależność mysql.
obesechicken13
2

Mój problem polegał na tym, że osadzona baza danych była już podłączona. ścisłe połączenie

doesnt_matter
źródło
1
Mogę potwierdzić, że istnieje jakiś problem z hibernacją, który zgłasza ten błąd, gdy nie może się połączyć. Mógłbym odtworzyć problem z włączaniem i wyłączaniem sieci.
borjab
2

Ten problem wystąpił, gdy Eclipse nie mógł znaleźć sterownika JDBC. Musiałem zrobić stopniowe odświeżenie z zaćmienia, aby uzyskać tę pracę.

Kannan Ramamoorthy
źródło
2

Oto niektóre z przyczyn hibernate.dialectnie ustawionego problemu. Większość tych wyjątków jest wyświetlana w dzienniku uruchamiania, po którym następuje wspomniany problem.

Przykład: W wiosennej aplikacji rozruchowej z Postgres DB

1. Sprawdź, czy baza danych jest faktycznie zainstalowana i czy serwer jest uruchomiony.

  • org.postgresql.util.PSQLException: Odmowa połączenia z hostem lokalnym: 5432 Sprawdź, czy nazwa hosta i port są poprawne oraz czy postmaster akceptuje połączenia TCP / IP.
  • java.net.ConnectException: Odmowa połączenia: połącz
  • org.hibernate.service.spi.ServiceException: Nie można utworzyć żądanej usługi [org.hibernate.engine.jdbc.env.spi.JdbcEnvironment]

2. Sprawdź, czy nazwa bazy danych jest poprawnie wymieniona.

  • org.postgresql.util.PSQLException: FATAL: baza danych „foo” nie istnieje

    W application.propertiespliku

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

    ale foonie istniało. Więc stworzyłem bazę danych z pgAdmin dla postgres

    CREATE DATABASE foo;

3. Sprawdź, czy nazwa hosta i port serwera są dostępne.

  • org.postgresql.util.PSQLException: Odmowa połączenia z hostem lokalnym: 5431 Sprawdź, czy nazwa hosta i port są poprawne oraz czy postmaster akceptuje połączenia TCP / IP.
  • java.net.ConnectException: Odmowa połączenia: połącz

4. Sprawdź, czy poświadczenia bazy danych są poprawne.

  • jak wspomniano @Pankaj
  • org.postgresql.util.PSQLException: FATAL: uwierzytelnienie hasła nie powiodło się dla użytkownika „postgres”

    spring.datasource.username= {DB USERNAME HERE}

    spring.datasource.password= {DB PASSWORD HERE}

abitcode
źródło
1

Jeśli używasz tej linii:

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

upewnij się, że env.getProperty("hibernate.dialect")nie jest to zero.

zygimantus
źródło
1

To samo, ale w JBoss WildFly AS .

Rozwiązany z właściwościami w moim 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>
Alejandro Teixeira Muñoz
źródło
1

Dla osób pracujących z AWS MySQL RDS może się zdarzyć, gdy nie będzie można połączyć się z bazą danych. Przejdź do ustawienia Grup bezpieczeństwa AWS dla MySQL RDS i edytuj regułę przychodzącego IP, odświeżając MyIP.

Napotkałem ten problem i wykonanie powyższej czynności rozwiązało problem.

Ajitesz
źródło
Zezwoliłem na cały ruch do grupy bezpieczeństwa RDS Aurora MySQL, to załatwiło sprawę. Jeśli chcesz być bardziej szczegółowy lub dla prod env, dodaj tylko dozwolone IPS
AleksandarT
1

Też miałem ten problem. W moim przypadku było to spowodowane tym, że użytkownikowi MySQL nie przydzielono żadnych dotacji. Przypisywanie dotacji użytkownikowi MySQL, z którego korzysta moja aplikacja, rozwiązało problem:

grant select, insert, delete, update on my_db.* to 'my_user'@'%';
Yamashiro Rion
źródło
1

Miałem ten sam problem i po debugowaniu okazuje się, że Spring application.properties miał zły adres IP dla serwera DB

spring.datasource.url=jdbc:oracle:thin:@WRONG:1521/DEV
JavaSheriff
źródło
1

Powtórzyłem ten komunikat o błędzie w następujących trzech przypadkach:

  • Nie istnieje użytkownik bazy danych o nazwie użytkownika zapisanej w pliku application.properties lub pliku persistence.properties lub, jak w twoim przypadku, w pliku HibernateConfig
  • Wdrożona baza danych ma tego użytkownika, ale użytkownik jest identyfikowany za pomocą innego hasła niż hasło w jednym z powyższych plików
  • Baza danych ma tego użytkownika i hasła, ale ten użytkownik nie ma wszystkich uprawnień potrzebnych do wykonania wszystkich zadań bazy danych, które wykonuje aplikacja Spring-boot

Oczywistym rozwiązaniem jest utworzenie nowego użytkownika bazy danych o tej samej nazwie użytkownika i haśle, co w aplikacji Spring-boot lub zmiana nazwy użytkownika i hasła w plikach aplikacji Spring-Boot, aby dopasować do istniejącego użytkownika bazy danych i przyznać wystarczające uprawnienia temu użytkownikowi bazy danych. W przypadku bazy danych MySQL można to zrobić, jak pokazano poniżej:

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

Oczywiście istnieją podobne polecenia w Postgresql, ale nie przetestowałem, czy w przypadku Postgresql ten komunikat o błędzie można odtworzyć w tych trzech przypadkach.

Veli-Matti Sorvala
źródło
0

Miałem ten sam problem i był on spowodowany niemożnością połączenia się z instancją bazy danych. Poszukaj błędu hibernacji HHH000342 w dzienniku powyżej tego błędu, powinien dać ci wyobrażenie o tym, gdzie nie działa połączenie db (niepoprawna nazwa użytkownika / hasło, adres URL itp.)

Farouk
źródło
0

Stało się tak, ponieważ nie dodałem conf.configure();przed rozpoczęciem sesji:

Configuration conf = new Configuration();
conf.configure();
Diana
źródło
0

Upewnij się, że wpisałeś poprawny szczegół w application.properties i czy twój serwer bazy danych jest dostępny. Jako przykład podczas łączenia się z MySQL sprawdź, czy XAMPP działa poprawnie.

Lahiru Gamage
źródło
0

Napotkałem ten sam problem: baza danych, z którą próbowałem się połączyć, nie istniała. Użyłem jpa.database=default(co chyba oznacza, że ​​spróbuje połączyć się z bazą danych, a następnie automatycznie wybierze dialekt). Gdy uruchomiłem bazę danych, działała dobrze bez żadnych zmian.

Avishekh Tewari
źródło
0

Napotkałem ten problem ze względu na to, że wersja Mysql 8.0.11 powróciła do 5.7 rozwiązana dla mnie

Gautam Yadav
źródło
0

Miałem ten sam błąd,

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

w moim przypadku WAR zawierał application.properties, które wskazywały na serwer programistyczny,
gdzie zewnętrzny application.properties wskazywał właściwy serwer DB.

upewnij się, że nie masz żadnych innych application.properties w ścieżce klasy / słoikach ...

JavaSheriff
źródło