org.hibernate.HibernateException: Akses ke DialectResolutionInfo tidak boleh nol ketika 'hibernate.dialect' tidak disetel

205

Saya mencoba menjalankan aplikasi spring-boot yang menggunakan hibernate via spring-jpa, tetapi saya mendapatkan kesalahan ini:

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

File pom.xml saya adalah ini:

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

konfigurasi hibernate saya adalah (konfigurasi dialek dalam metode terakhir dari kelas ini):

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

apa yang saya lakukan salah di sini?

Kleber Mota
sumber

Jawaban:

201

Pertama-tama hapus semua konfigurasi Anda. Boot Musim Semi akan memulainya untuk Anda.

Pastikan Anda memiliki application.propertiesdi classpath Anda dan tambahkan properti berikut.

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

Jika Anda benar-benar membutuhkan akses ke SessionFactorydan itu pada dasarnya untuk sumber data yang sama, maka Anda dapat melakukan hal berikut (yang juga didokumentasikan di sini meskipun untuk XML, bukan JavaConfig).

@Configuration        
public class HibernateConfig {

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

Dengan begitu Anda memiliki kedua EntityManagerFactorydan SessionFactory.

UPDATE: Pada Hibernate 5 yang SessionFactorysebenarnya memperpanjang EntityManagerFactory. Jadi untuk mendapatkan SessionFactoryAnda cukup melemparkannya EntityManagerFactoryatau menggunakan unwrapmetode untuk mendapatkannya.

public class SomeHibernateRepository {

  @PersistenceUnit
  private EntityManagerFactory emf;

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

}

Dengan asumsi Anda memiliki kelas dengan mainmetode yang @EnableAutoConfigurationAnda tidak perlu @EnableTransactionManagementpenjelasan, karena itu akan diaktifkan oleh Spring Boot untuk Anda. Kelas aplikasi dasar dalam com.spring.apppaket harus cukup.

@Configuration
@EnableAutoConfiguration
@ComponentScan
public class Application {


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

} 

Sesuatu seperti itu harus cukup untuk memiliki semua kelas Anda (termasuk entitas dan repositori berbasis Spring Data) terdeteksi.

UPDATE: Anotasi ini dapat diganti dengan satu @SpringBootApplicationdi Spring Boot versi terbaru.

@SpringBootApplication
public class Application {

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

Saya juga menyarankan menghapus commons-dbcpketergantungan karena itu akan memungkinkan Spring Boot untuk mengkonfigurasi HikariCPimplementasi yang lebih cepat dan lebih kuat .

M. Deinum
sumber
1
tetapi apakah ada cara untuk menghindari membuat file ini application.propertes? Saya lebih suka cara di mana saya melakukan semua konfigurasi di kelas HibernateConfig.
Kleber Mota
2
Mengapa? Seluruh tujuan Spring Boot adalah melakukan konfigurasi otomatis untuk Anda ... Jadi, Anda lebih suka menyertakan konfigurasi java verbose lebih dari 7 baris dalam file properti ?!
M. Deinum
2
Bahkan bisa 6 baris dalam file properti. Anda tidak perlu mengatur spring.datasource.driverClassName ketika Anda menggunakan Postgres karena Boot akan menyimpulkannya dari spring.datasource.url.
Andy Wilkinson
2
@AlexWorden Tidak bukan ... Alih-alih memberikan komentar acak, Anda mungkin pertama-tama ingin membaca bagaimana properti dimuat terutama dukungan yang dimiliki Spring Boot. Kata sandi pada disk tidak harus menjadi masalah jika Anda meluruskan hak file. Menempatkan mereka dalam database tidak jauh lebih baik ...
M. Deinum
4
Alih-alih menggunakan 3 anotasi yaitu Konfigurasi, EnableAutoConfiguration, ComponentScan. Kita dapat menggunakan anotasi SpringBootApplication
Pankaj 8'15
159

Saya menghadapi masalah yang sama ketika memulai aplikasi (menggunakan Spring Boot) dengan server database turun .

Hibernate dapat menentukan dialek yang benar untuk digunakan secara otomatis, tetapi untuk melakukan ini, perlu koneksi langsung ke database.

mhnagaoka
sumber
2
Masalah saya mirip dengan ini dalam pg_hba.conf di server tidak dikonfigurasi untuk koneksi jarak jauh, yang memberi saya kesalahan ini.
Brian
8
Jika database yang Anda coba sambungkan tidak ada, Anda juga melihat kesalahan ini.
Jonas Pedersen
12
Punya masalah yang sama, dalam kasus saya DB naik tetapi kredensial salah. +1
Federico Piazza
mengherankan saya mulai mendapatkan masalah ini ketika menjatuhkan skema mengharapkan hbm2ddl.auto = true akan membuat db dan tabel. namun gagal. tetapi jika saya membuat skema kosong, hbm2ddl bekerja membuat tabel
Saurabh
IP dari mesin basis data telah diubah tetapi DNS telah memutuskan untuk yang lama :-(
Illidan
24

tambahkan spring.jpa.properties.hibernate.dialect = org.hibernate.dialect.MySQLDialectfile application.properties

alpine
sumber
Ini adalah jawaban yang bagus - memungkinkan saya menggunakan MockBean untuk kelas basis data dan tidak memiliki informasi koneksi nyata di profil properti saya
Taylor
Menambahkan spring.jpa.properties.hibernate.dialect ke application.properties membantu saya. Terima kasih)
Maks
22

Saya mendapatkan kesalahan ini ketika database saya tidak dibuat. Setelah membuat DB secara manual, itu berfungsi dengan baik.

ACV
sumber
1
Biasanya Anda dapat menghindari pembuatan manual dengan menggunakan "spring.jpa.hibernate.ddl-auto = create"
Andrei
@Andrei - bagaimana / di mana saya akan menentukan "spring.jpa.hibernate.ddl-auto = create"?
Alex Worden
2
@AlexWorden, Andrei berarti Anda dapat meletakkannya di application.properties jika itu adalah Spring Boot. Harus ada yang setara untuk konfigurasi Spring berbasis xml.
ACV
Apakah kesalahan ini hanya muncul ketika database tidak ada atau juga ketika tabel di dalam database tidak ada?
zygimantus
1
Saya telah memberikan kata sandi yang salah dan saya menghadapi kesalahan yang sama. Terima kasih ACV, Anda banyak membantu saya.
santu
17

Saya juga menghadapi masalah serupa. Tapi, itu karena kata sandi yang diberikan tidak valid. Juga, saya ingin mengatakan kode Anda sepertinya kode gaya lama menggunakan pegas. Anda telah menyebutkan bahwa Anda menggunakan spring boot, yang berarti sebagian besar hal akan dikonfigurasi secara otomatis untuk Anda. dialek hibernate akan dipilih secara otomatis berdasarkan driver DB yang tersedia di classpath bersama dengan kredensial yang valid yang dapat digunakan untuk menguji koneksi dengan benar. Jika ada masalah dengan koneksi Anda akan kembali menghadapi kesalahan yang sama. hanya 3 properti yang diperlukan di 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
sumber
8

Saya mengalami masalah yang sama dan masalah saya adalah bahwa DB yang saya coba hubungkan tidak ada.

Saya membuat DB, memverifikasi URL / koneksi string dan reran dan semuanya berfungsi seperti yang diharapkan.

Eric B.
sumber
Terima kasih komentar Anda mengarahkan saya untuk memeriksa port koneksi yang salah
Feras
4

ini terjadi karena kode Anda tidak bale untuk menghubungkan database. Pastikan Anda memiliki driver mysql dan nama pengguna, kata sandi yang benar.

pengguna7169604
sumber
4

Pastikan Anda application.propertiesmemiliki semua info yang benar: (Saya mengubah port db dari saya 8889agar 3306berfungsi)

 db.url: jdbc:mysql://localhost:3306/test
Vikram S
sumber
4

Di spring boot untuk jpa java config, Anda perlu memperluas JpaBaseConfiguration dan mengimplementasikan metode abstraknya.

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

}
Yaroslav
sumber
beberapa kasus application.properties tidak dapat melihat perubahan properti. Dan saya menambahkan properties.put seperti di atas dan berfungsi dengan baik. Terima kasih.
fatih yavuz
4

Hapus Konfigurasi Hibernate yang berlebihan

Jika Anda menggunakan Spring Boot, Anda tidak perlu memberikan konfigurasi JPA dan Hibernate secara eksplisit, karena Spring Boot dapat melakukannya untuk Anda.

Tambahkan properti konfigurasi basis data

Di application.propertiesfile konfigurasi Spring Boot, Anda harus menambahkan properti konfigurasi database Anda:

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

Tambahkan Hibernate properti spesifik

Dan, dalam application.propertiesfile konfigurasi yang sama , Anda juga dapat mengatur properti Hibernate kustom:

# 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

Itu dia!

Vlad Mihalcea
sumber
Menambahkan spring.jpa.properties.hibernate.dialect ke application.properties membantu saya. Terima kasih)
Maks
3

Saya memiliki masalah yang sama. menambahkan ini ke application.properties memecahkan masalah:

spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQLDialect
Arthur Kazemi
sumber
Menambahkan spring.jpa.properties.hibernate.dialect ke application.properties membantu saya. Terima kasih)
Maks
2

Dalam kasus saya, pengguna tidak dapat terhubung ke database. Jika akan memiliki masalah yang sama jika log berisi peringatan sebelum pengecualian:

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

Pastikan Anda memiliki database di pom Anda seperti OP lakukan. Itu masalah saya.

obesechicken13
sumber
Bisakah Anda menguraikan lebih jauh? Apa yang Anda maksud dengan jawaban ini?
Tunaki
Saya hanya perlu menambahkan ketergantungan mysql.
obesechicken13
2

Masalah saya adalah bahwa database tertanam sudah terhubung. koneksi dekat

doesnt_matter
sumber
1
Saya dapat mengonfirmasi bahwa ada beberapa jenis masalah Hibernate yang melaporkan kesalahan ini ketika gagal terhubung. Saya bisa mereproduksi masalah dengan menghidupkan dan mematikan jaringan.
borjab
2

Saya mendapatkan masalah ini ketika Eclipse tidak dapat menemukan driver JDBC. Harus melakukan refresh gradle dari gerhana untuk mendapatkan pekerjaan ini.

Kannan Ramamoorthy
sumber
2

Berikut ini adalah beberapa alasan untuk masalah yang hibernate.dialecttidak diatur. Sebagian besar pengecualian ini ditampilkan di log startup yang akhirnya diikuti oleh masalah yang disebutkan.

Contoh: Di aplikasi Booting musim semi dengan Postgres DB

1. Periksa apakah database benar-benar diinstal dan servernya dimulai.

  • org.postgresql.util.PSQLException: Sambungan ke localhost: 5432 ditolak. Periksa apakah nama host dan port sudah benar dan bahwa kepala kantor pos menerima koneksi TCP / IP.
  • java.net.ConnectException: Sambungan ditolak: terhubung
  • org.hibernate.service.spi.ServiceException: Tidak dapat membuat layanan yang diminta [org.hibernate.engine.jdbc.env.spi.JdbcEnvironment]

2. Periksa apakah nama database disebutkan dengan benar.

  • org.postgresql.util.PSQLEeksepsi: FATAL: database "foo" tidak ada

    Dalam application.propertiesfile,

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

    tetapi footidak ada. Jadi saya membuat database dari pgAdmin untuk postgres

    CREATE DATABASE foo;

3. Periksa apakah nama host dan port server dapat diakses.

  • org.postgresql.util.PSQLException: Sambungan ke localhost: 5431 ditolak. Periksa apakah nama host dan port sudah benar dan bahwa kepala kantor pos menerima koneksi TCP / IP.
  • java.net.ConnectException: Sambungan ditolak: terhubung

4. Periksa apakah kredensial database sudah benar.

  • seperti yang disebutkan @Pankaj
  • org.postgresql.util.PSQLException: FATAL: otentikasi kata sandi gagal untuk "postgres" pengguna

    spring.datasource.username= {DB USERNAME HERE}

    spring.datasource.password= {DB PASSWORD HERE}

abitcode
sumber
1

Jika Anda menggunakan baris ini:

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

pastikan itu env.getProperty("hibernate.dialect")bukan nol.

zygimantus
sumber
1

Sama tetapi dalam JBoss WildFly AS .

Diselesaikan dengan properti di my 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
sumber
1

Bagi mereka yang bekerja dengan AWS MySQL RDS, ini dapat terjadi ketika Anda tidak dapat terhubung ke database. Pergi ke pengaturan Grup Keamanan AWS untuk MySQL RDS dan edit aturan IP masuk dengan menyegarkan MyIP.

Saya menghadapi masalah ini dan melakukan di atas menyelesaikan masalah untuk saya.

Ajitesh
sumber
Saya mengizinkan semua lalu lintas ke grup keamanan RDS Aurora MySQL, ini berhasil bagi saya. Jika Anda ingin lebih spesifik atau untuk produk, tambahkan hanya ips yang diizinkan
AleksandarT
1

Saya juga punya masalah ini. Dalam kasus saya itu karena tidak ada hibah yang diberikan kepada pengguna MySQL. Menetapkan hibah kepada pengguna MySQL yang digunakan aplikasi saya menyelesaikan masalah:

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

Saya memiliki masalah yang sama dan setelah debugging ternyata Spring application.properties memiliki alamat IP yang salah untuk server DB

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

Saya mereproduksi pesan kesalahan ini dalam tiga kasus berikut:

  • Tidak ada pengguna basis data dengan nama pengguna yang ditulis dalam file application.properties atau file persistence.properties atau, seperti dalam kasus Anda, dalam file HibernateConfig
  • Basis data yang dikerahkan memiliki pengguna itu tetapi pengguna diidentifikasi dengan kata sandi yang berbeda dari yang ada di salah satu file di atas
  • Basis data memiliki pengguna dan kata sandi yang cocok tetapi pengguna tersebut tidak memiliki semua hak istimewa yang diperlukan untuk menyelesaikan semua tugas basis data yang dilakukan oleh aplikasi boot-pegas Anda

Solusi yang jelas adalah membuat pengguna basis data baru dengan nama pengguna dan kata sandi yang sama seperti pada aplikasi pegas-boot atau mengubah nama pengguna dan kata sandi dalam file aplikasi pegas-boot Anda untuk mencocokkan pengguna database yang ada dan memberikan hak yang cukup kepada pengguna database tersebut. Dalam hal database MySQL ini dapat dilakukan seperti yang ditunjukkan di bawah ini:

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

Jelas ada perintah serupa di Postgresql tapi saya belum menguji jika dalam kasus Postgresql pesan kesalahan ini dapat direproduksi dalam tiga kasus ini.

Veli-Matti Sorvala
sumber
0

Saya memiliki masalah yang sama dan itu disebabkan karena tidak dapat terhubung ke instance database. Cari kesalahan hibernasi HHH000342 di log di atas kesalahan itu, itu akan memberi Anda gambaran di mana koneksi db gagal (salah nama pengguna / pass, url, dll.)

Farouk
sumber
0

Ini terjadi pada saya karena saya belum menambahkan conf.configure();sebelum memulai sesi:

Configuration conf = new Configuration();
conf.configure();
diana
sumber
0

Pastikan Anda telah memasukkan detail yang valid di application.properties dan apakah server database Anda tersedia. Sebagai contoh ketika Anda terhubung dengan MySQL, periksa apakah XAMPP berjalan dengan benar.

Lahiru Gamage
sumber
0

Saya menghadapi masalah yang sama: db yang saya coba hubungkan tidak ada. Saya menggunakan jpa.database=default(yang saya kira artinya akan mencoba untuk terhubung ke database dan kemudian pilih dialek secara otomatis). Setelah saya memulai database, itu bekerja dengan baik tanpa perubahan apa pun.

Avishekh Tewari
sumber
0

Saya menghadapi masalah ini karena versi Mysql 8.0.11 kembali ke 5.7 diselesaikan untuk saya

Gautam Yadav
sumber
0

Saya memiliki Kesalahan yang sama,

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

dalam kasus saya PERANG memiliki application.properties di dalam yang menunjuk ke server pengembangan di
mana application.properties eksternal menunjuk ke server DB yang tepat.

pastikan Anda tidak memiliki aplikasi lain. Properti di classpath / guci ...

JavaSheriff
sumber