HibernateException:使用DefaultSchemaNameResolver要求Dialect提供正确的SQL语句/命令

时间:2019-04-17 08:50:45

标签: spring postgresql hibernate spring-boot

我正在运行Spring Boot应用程序2.1.4.RELEASE。该应用程序使用的是Hibernate 5.4.2.Final和postgresql驱动程序版本42.2.5。最近,我试图从休眠状态生成DDL以查看DDL,但我偶然发现了一个错误,该错误自几天以来一直困扰着我。 使用PostgreSQL 11.2版本(Ubuntu 11.2-1.pgdg18.04 + 1)

现在,当应用程序启动时,它每次都会遇到该异常。

如果我在方法上放置一个断点

org.hibernate.engine.jdbc.env.internal.DefaultSchemaNameResolver.determineAppropriateResolverDelegate(Connection connection)

我可以看到发生异常的地方,即

connection.getSchema();

该课程中有有用的评论

unfortunately Connection#getSchema is only available in Java 1.7 and above
and Hibernate still baselines on 1.6.  So for now, use reflection and
leverage the Connection#getSchema method if it is available.

If the JDBC driver does not implement the Java 7 spec, but the JRE is Java 7
then the getSchemaMethod is not null but the call to getSchema() throws an java.lang.AbstractMethodError

我正在运行高于7的版本,即:

java -version
openjdk version "11" 2018-09-25
OpenJDK Runtime Environment 18.9 (build 11+28)
OpenJDK 64-Bit Server VM 18.9 (build 11+28, mixed mode)

我在Spring Boot启动时仍然遇到以下异常,即!!!!甚至在代码的一部分(豆子)都达到之前!!!可以生成DDL的对象,即方法createSchemaWithHibernate5(LocalSessionFactoryBean sessionFactory)。 因此,这与配置或连接类型有关。当我在连接类型上放置断点时,我看到它的类型为

org.apache.commons.dbcp.PoolableConnection

好吧,它是从“ DelegatingConnection”扩展而来的,尽管它正在扩展接口,但它并未实现getSchema()方法

java.sql.Connection 

确实具有方法getSchema()。 我不确定这应该如何工作,因为这些都不是最终类或抽象类。

我还看到了另一个名为

的类
org.postgresql.jdbc.PgConnection. 

由于我确实看到该应用程序确实实现了getSchema()方法,因此该如何强制我的应用程序使用该应用程序。

这是我遇到的例外情况:

2019-04-17 10:06:42.487 DEBUG tito-pc --- [  restartedMain] .i.f.i.DefaultIdentifierGeneratorFactory : Registering IdentifierGenerator strategy [enhanced-table] -> [org.hibernate.id.enhanced.TableGenerator]
2019-04-17 10:06:43.004 DEBUG tito-pc --- [  restartedMain] o.h.e.j.e.i.JdbcEnvironmentInitiator     : Database ->
       name : PostgreSQL
    version : 11.2 (Ubuntu 11.2-1.pgdg18.04+1)
      major : 11
      minor : 2
2019-04-17 10:06:43.004 DEBUG tito-pc --- [  restartedMain] o.h.e.j.e.i.JdbcEnvironmentInitiator     : Driver ->
       name : PostgreSQL JDBC Driver
    version : 42.2.5
      major : 42
      minor : 2
2019-04-17 10:06:43.005 DEBUG tito-pc --- [  restartedMain] o.h.e.j.e.i.JdbcEnvironmentInitiator     : JDBC version : 4.2
2019-04-17 10:06:43.023  INFO tito-pc --- [  restartedMain] o.h.d.Dialect                            : HHH000400: Using dialect: org.hibernate.dialect.PostgreSQL95Dialect
2019-04-17 10:06:43.053 DEBUG tito-pc --- [  restartedMain] o.h.e.j.e.s.IdentifierHelperBuilder      : JDBC driver metadata reported database stores quoted identifiers in neither upper, lower nor mixed case
2019-04-17 10:06:54.515 DEBUG tito-pc --- [  restartedMain] o.h.e.j.e.i.DefaultSchemaNameResolver    : Unable to use Java 1.7 Connection#getSchema
2019-04-17 10:06:59.058 DEBUG tito-pc --- [  restartedMain] o.h.e.j.e.i.JdbcEnvironmentImpl          : Unable to resolve connection default schema
org.hibernate.HibernateException: Use of DefaultSchemaNameResolver requires Dialect to provide the proper SQL statement/command but provided Dialect [org.hibernate.dialect.PostgreSQL95Dialect] did not return anything from Dialect#getCurrentSchemaCommand
    at org.hibernate.engine.jdbc.env.internal.DefaultSchemaNameResolver$SchemaNameResolverFallbackDelegate.resolveSchemaName(DefaultSchemaNameResolver.java:100)
    at org.hibernate.engine.jdbc.env.internal.DefaultSchemaNameResolver.resolveSchemaName(DefaultSchemaNameResolver.java:76)
    at org.hibernate.engine.jdbc.env.internal.JdbcEnvironmentImpl.determineCurrentSchemaName(JdbcEnvironmentImpl.java:311)
    at org.hibernate.engine.jdbc.env.internal.JdbcEnvironmentImpl.<init>(JdbcEnvironmentImpl.java:266)
    at org.hibernate.engine.jdbc.env.internal.JdbcEnvironmentInitiator.initiateService(JdbcEnvironmentInitiator.java:114)
    at org.hibernate.engine.jdbc.env.internal.JdbcEnvironmentInitiator.initiateService(JdbcEnvironmentInitiator.java:35)
    at org.hibernate.boot.registry.internal.StandardServiceRegistryImpl.initiateService(StandardServiceRegistryImpl.java:101)
    at org.hibernate.service.internal.AbstractServiceRegistryImpl.createService(AbstractServiceRegistryImpl.java:263)
    at org.hibernate.service.internal.AbstractServiceRegistryImpl.initializeService(AbstractServiceRegistryImpl.java:237)
    at org.hibernate.service.internal.AbstractServiceRegistryImpl.getService(AbstractServiceRegistryImpl.java:214)
    at org.hibernate.id.factory.internal.DefaultIdentifierGeneratorFactory.injectServices(DefaultIdentifierGeneratorFactory.java:152)
    at org.hibernate.service.internal.AbstractServiceRegistryImpl.injectDependencies(AbstractServiceRegistryImpl.java:286)
    at org.hibernate.service.internal.AbstractServiceRegistryImpl.initializeService(AbstractServiceRegistryImpl.java:243)
    at org.hibernate.service.internal.AbstractServiceRegistryImpl.getService(AbstractServiceRegistryImpl.java:214)
    at org.hibernate.boot.internal.InFlightMetadataCollectorImpl.<init>(InFlightMetadataCollectorImpl.java:175)
    at org.hibernate.boot.model.process.spi.MetadataBuildingProcess.complete(MetadataBuildingProcess.java:118)
    at org.hibernate.boot.model.process.spi.MetadataBuildingProcess.build(MetadataBuildingProcess.java:83)
    at org.hibernate.boot.internal.MetadataBuilderImpl.build(MetadataBuilderImpl.java:473)
    at org.hibernate.boot.internal.MetadataBuilderImpl.build(MetadataBuilderImpl.java:84)
    at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:689)
    at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:724)
    at org.springframework.orm.hibernate5.LocalSessionFactoryBean.buildSessionFactory(LocalSessionFactoryBean.java:615)
    at org.springframework.orm.hibernate5.LocalSessionFactoryBean.afterPropertiesSet(LocalSessionFactoryBean.java:599)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1837)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1774)
    .....

这是我的持久性配置:

@Profile("Development")
@Configuration
@EnableTransactionManagement
@Order(value=1)
public class PersistenceConfigDevelopment {


    private static Logger logger = LogManager.getLogger(PersistenceConfigDevelopment.class.getName());

    @Bean
    @Primary
    public org.apache.commons.dbcp.BasicDataSource dataSourceReadWrite1() {

        BasicDataSource dataSource = new BasicDataSource();
        dataSource.setDriverClassName("org.postgresql.Driver");
        dataSource.setUrl("jdbc:postgresql://localhost:5432/develpmentTestDb");
        dataSource.setUsername("admin");
        dataSource.setPassword("notABigSecret");
        dataSource.setInitialSize(20);
        dataSource.setMaxActive(-1);


        return dataSource;
    }




    @Bean
    @Primary
    public org.springframework.orm.hibernate5.LocalSessionFactoryBean sessionFactory() {

        org.springframework.orm.hibernate5.LocalSessionFactoryBean sessionFactory = new LocalSessionFactoryBean();
        sessionFactory.setHibernateProperties(hibernateProperties());
        sessionFactory.setDataSource(this.dataSourceReadWrite1());
        sessionFactory.setPackagesToScan("org.university.");


        return sessionFactory;
    }

    @Bean
    public HibernateTransactionManager transactionManager() {
        HibernateTransactionManager txManager = new HibernateTransactionManager();
        txManager.setSessionFactory(sessionFactory().getObject());

        return txManager;
    }

    @Bean
    public PersistenceExceptionTranslationPostProcessor exceptionTranslation() {
        return new PersistenceExceptionTranslationPostProcessor();
    }   


    @Bean
    public Properties hibernateProperties() {
        return new Properties() {
            /**
             * 
             */
            private static final long serialVersionUID = 1L;

            {
                setProperty("hibernate.dialect", "org.hibernate.dialect.PostgreSQL95Dialect");
                setProperty("hibernate.chach.provider_class", "org.hibernate.cache.NoCacheProvider");
                setProperty("hibernate.show_sql", "true");
                setProperty("hibernate.hbm2ddl.auto", "create-drop");

                setProperty("hibernate.cache.use_second_level_cache", "false");
                setProperty("hibernate.cache.use_query_cache", "false");

                // isolation level
                setProperty("hibernate.connection.isolation", String.valueOf(Connection.TRANSACTION_SERIALIZABLE));


            }
        };
    }       

    @Bean
    public Boolean createSchemaWithHibernate5(LocalSessionFactoryBean sessionFactory) {

        final PostgreSQL95Dialect dialect = new PostgreSQL95Dialect();
        StandardServiceRegistry serviceRegistry = sessionFactory.getConfiguration().getStandardServiceRegistryBuilder()
                .applySetting("hibernate.dialect", dialect)
                .build();

        Metadata metadata = new MetadataSources(serviceRegistry).buildMetadata();

        new SchemaExport() 
                .setOutputFile("db-schema.hibernate5.ddl") 
                .create(EnumSet.of(TargetType.SCRIPT), metadata);

        metadata.buildSessionFactory().close();

        return Boolean.TRUE;
    }


}

由于这个stackoverflow帖子,我尝试更改驱动程序,即

Implementating Method org.postgresql.jdbc4.Jdbc4Connection.getSchema()

并尝试使用“ postgresql” Maven构件代替“ org.postgresql”,但这并没有帮助。

我们非常感谢您的帮助。

        <dependency>
            <groupId>org.postgresql</groupId>
            <artifactId>postgresql</artifactId>
<!--             <version>${orgpostgresql.version}</version> -->
        </dependency>

<!--         <dependency> -->
<!--             <groupId>postgresql</groupId> -->
<!--             <artifactId>postgresql</artifactId> -->
<!--             <version>${postgresql.version}</version> -->
<!--         </dependency> -->

更新4月17日

我可以通过使用另一个数据源(即PGSimpleDataSource)来消除异常,该数据源也将连接器更改为PgConnection,但仍未生成DDL。即会生成db-schema.hibernate5.ddl文件,但它为空。

@Bean
@Primary
public PGSimpleDataSource dataSourceReadWrite1() {

    PGSimpleDataSource dataSource = new PGSimpleDataSource();
    dataSource.setUrl("jdbc:postgresql://localhost:5432/developmentTestDB");
    dataSource.setUser("admin");
    dataSource.setPassword("notABigSecret");


    return dataSource;
}

0 个答案:

没有答案