1. ホーム
  2. スクリプト・コラム
  3. その他

[解決済み】org.hibernate.HibernateException: hibernate.dialect' が設定されていない場合、DialectResolutionInfo へのアクセスは null にできません。

2022-01-11 02:39:14

質問

springbootプロジェクトで、spring-jpa経由でhibernateを使用しています。

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

プロジェクトを実行すると、エラーが発生します。

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

解決方法は?

まず、設定をすべて削除します。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 で、それが基本的に同じデータソースに対するものであれば、次のようにすることができます (これもドキュメントに書かれています)。 ここで ただし、JavaConfigではなく、XMLの場合)。

@Configuration        
public class HibernateConfig {

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

この方法では EntityManagerFactorySessionFactory .

UPDATE 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ベースのリポジトリを含む)を検出するのに十分でしょう。

UPDATEしてください。 これらのアノテーションは、単一の @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 の実装があります。