org.hibernate.HibernateException:当未设置“hibernate.dialect"时,对 DialectResolutionInfo 的访问不能为空 [英] org.hibernate.HibernateException: Access to DialectResolutionInfo cannot be null when 'hibernate.dialect' not set
问题描述
我正在尝试通过 spring-jpa 运行使用休眠的 spring-boot 应用程序,但我收到此错误:
I am trying run a spring-boot application which uses hibernate via spring-jpa, but i am getting this error:
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 文件是这样的:
my pom.xml file is this:
<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>
我的休眠配置是这样的(方言配置在这个类的最后一个方法中):
my hibernate configuration is that (the dialect configuration is in the last method from this class):
@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 会为你启动它.
First remove all of your configuration Spring Boot will start it for you.
确保您的类路径中有 application.properties
并添加以下属性.
Make sure you have an application.properties
in your classpath and add the following 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
并且基本上是针对相同的数据源,那么您可以执行以下操作(也记录在 这里 虽然是 XML,不是 JavaConfig).
If you really need access to a SessionFactory
and that is basically for the same datasource, then you can do the following (which is also documented here although for XML, not JavaConfig).
@Configuration
public class HibernateConfig {
@Bean
public HibernateJpaSessionFactoryBean sessionFactory(EntityManagerFactory emf) {
HibernateJpaSessionFactoryBean factory = new HibernateJpaSessionFactoryBean();
factory.setEntityManagerFactory(emf);
return factory;
}
}
这样你就有了 EntityManagerFactory
和 SessionFactory
.
That way you have both an EntityManagerFactory
and a SessionFactory
.
更新:从 Hibernate 5 开始,SessionFactory
实际上扩展了 EntityManagerFactory
.因此,要获得 SessionFactory
,您可以简单地将 EntityManagerFactory
转换为它或使用 unwrap
方法来获取.
UPDATE: As of Hibernate 5 the SessionFactory
actually extends the EntityManagerFactory
. So to obtain a SessionFactory
you can simply cast the EntityManagerFactory
to it or use the unwrap
method to get one.
public class SomeHibernateRepository {
@PersistenceUnit
private EntityManagerFactory emf;
protected SessionFactory getSessionFactory() {
return emf.unwrap(SessionFactory.class);
}
}
假设您有一个带有 @EnableAutoConfiguration
的 main
方法的类,您不需要 @EnableTransactionManagement
注释,因为那将是由 Spring Boot 为您启用.com.spring.app
包中的一个基本应用程序类就足够了.
Assuming you have a class with a main
method with @EnableAutoConfiguration
you don't need the @EnableTransactionManagement
annotation, as that will be enabled by Spring Boot for you. A basic application class in the com.spring.app
package should be enough.
@Configuration
@EnableAutoConfiguration
@ComponentScan
public class Application {
public static void main(String[] args) throws Exception {
SpringApplication.run(Application.class, args);
}
}
这样的事情应该足以检测到您的所有类(包括实体和基于 Spring Data 的存储库).
Something like that should be enough to have all your classes (including entities and Spring Data based repositories) detected.
更新:在较新版本的 Spring Boot 中,这些注释可以替换为单个 @SpringBootApplication
.
UPDATE: These annotations can be replaced with a single @SpringBootApplication
in more recent versions of Spring Boot.
@SpringBootApplication
public class Application {
public static void main(String[] args) throws Exception {
SpringApplication.run(Application.class, args);
}
}
我还建议删除 commons-dbcp
依赖项,因为这将允许 Spring Boot 配置更快、更健壮的 HikariCP
实现.
I would also suggest removing the commons-dbcp
dependency as that would allow Spring Boot to configure the faster and more robust HikariCP
implementation.
这篇关于org.hibernate.HibernateException:当未设置“hibernate.dialect"时,对 DialectResolutionInfo 的访问不能为空的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!