LoginSignup
13
10

More than 5 years have passed since last update.

HibernateでPostgreSQLに接続する際の初期化時エラー

Last updated at Posted at 2016-06-05

HibernateでPostgreSQLを利用する場合に、アプリケーションの初期化時に以下のようなエラーが出たので調査した結果をまとめます。

結論から言うと、無視して良さそうなエラーでした。

java.sql.SQLFeatureNotSupportedException: org.postgresql.jdbc.PgConnection.createClob() メソッドはまだ実装されていません。
        at org.postgresql.Driver.notImplemented(Driver.java:646) ~[postgresql-9.4.1208.jar:9.4.1208]
        at org.postgresql.jdbc.PgConnection.createClob(PgConnection.java:1281) ~[postgresql-9.4.1208.jar:9.4.1208]
        at org.apache.commons.dbcp2.DelegatingConnection.createClob(DelegatingConnection.java:868) ~[commons-dbcp2-2.1.1.jar:2.1.1]
        at org.apache.commons.dbcp2.DelegatingConnection.createClob(DelegatingConnection.java:868) ~[commons-dbcp2-2.1.1.jar:2.1.1]
        at net.sf.log4jdbc.ConnectionSpy.createClob(ConnectionSpy.java:496) ~[log4jdbc-remix-0.2.7.jar:na]
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_77]
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:1.8.0_77]
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_77]
        at java.lang.reflect.Method.invoke(Method.java:498) ~[na:1.8.0_77]
        at org.hibernate.engine.jdbc.internal.LobCreatorBuilder.useContextualLobCreation(LobCreatorBuilder.java:112) [hibernate-core-4.3.11.Final.jar:4.3.11.Final]
        at org.hibernate.engine.jdbc.internal.LobCreatorBuilder.<init>(LobCreatorBuilder.java:63) [hibernate-core-4.3.11.Final.jar:4.3.11.Final]
        at org.hibernate.engine.jdbc.internal.JdbcServicesImpl.configure(JdbcServicesImpl.java:192) [hibernate-core-4.3.11.Final.jar:4.3.11.Final]
        at org.hibernate.boot.registry.internal.StandardServiceRegistryImpl.configureService(StandardServiceRegistryImpl.java:111) [hibernate-core-4.3.11.Final.jar:4.3.11.Final]
        at org.hibernate.service.internal.AbstractServiceRegistryImpl.initializeService(AbstractServiceRegistryImpl.java:234) [hibernate-core-4.3.11.Final.jar:4.3.11.Final]
        at org.hibernate.service.internal.AbstractServiceRegistryImpl.getService(AbstractServiceRegistryImpl.java:206) [hibernate-core-4.3.11.Final.jar:4.3.11.Final]
        at org.hibernate.cfg.Configuration.buildTypeRegistrations(Configuration.java:1887) [hibernate-core-4.3.11.Final.jar:4.3.11.Final]
        at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:1845) [hibernate-core-4.3.11.Final.jar:4.3.11.Final]
        at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl$4.perform(EntityManagerFactoryBuilderImpl.java:857) [hibernate-entitymanager-4.3.11.Final.jar:4.3.11.Final]
        at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl$4.perform(EntityManagerFactoryBuilderImpl.java:850) [hibernate-entitymanager-4.3.11.Final.jar:4.3.11.Final]
        at org.hibernate.boot.registry.classloading.internal.ClassLoaderServiceImpl.withTccl(ClassLoaderServiceImpl.java:425) [hibernate-core-4.3.11.Final.jar:4.3.11.Final]
        at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.build(EntityManagerFactoryBuilderImpl.java:849) [hibernate-entitymanager-4.3.11.Final.jar:4.3.11.Final]
        at org.springframework.orm.jpa.vendor.SpringHibernateJpaPersistenceProvider.createContainerEntityManagerFactory(SpringHibernateJpaPersistenceProvider.java:60) [spring-orm-4.2.4.RELEASE.jar:4.2.4.RELEASE]
        at org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean.createNativeEntityManagerFactory(LocalContainerEntityManagerFactoryBean.java:343) [spring-orm-4.2.4.RELEASE.jar:4.2.4.RELEASE]
        at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.afterPropertiesSet(AbstractEntityManagerFactoryBean.java:318) [spring-orm-4.2.4.RELEASE.jar:4.2.4.RELEASE]
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1637) [spring-beans-4.2.4.RELEASE.jar:4.2.4.RELEASE]
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1574) [spring-beans-4.2.4.RELEASE.jar:4.2.4.RELEASE]
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:545) [spring-beans-4.2.4.RELEASE.jar:4.2.4.RELEASE]
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:482) [spring-beans-4.2.4.RELEASE.jar:4.2.4.RELEASE]
        at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:306) [spring-beans-4.2.4.RELEASE.jar:4.2.4.RELEASE]
        at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230) [spring-beans-4.2.4.RELEASE.jar:4.2.4.RELEASE]
        at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:302) [spring-beans-4.2.4.RELEASE.jar:4.2.4.RELEASE]
        at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:197) [spring-beans-4.2.4.RELEASE.jar:4.2.4.RELEASE]
        at org.springframework.context.support.AbstractApplicationContext.getBean(AbstractApplicationContext.java:1054) [spring-context-4.2.4.RELEASE.jar:4.2.4.RELEASE]
        at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:829) [spring-context-4.2.4.RELEASE.jar:4.2.4.RELEASE]
        at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:538) [spring-context-4.2.4.RELEASE.jar:4.2.4.RELEASE]
        at org.springframework.web.context.ContextLoader.configureAndRefreshWebApplicationContext(ContextLoader.java:446) [spring-web-4.2.4.RELEASE.jar:4.2.4.RELEASE]
        at org.springframework.web.context.ContextLoader.initWebApplicationContext(ContextLoader.java:328) [spring-web-4.2.4.RELEASE.jar:4.2.4.RELEASE]
        at org.springframework.web.context.ContextLoaderListener.contextInitialized(ContextLoaderListener.java:107) [spring-web-4.2.4.RELEASE.jar:4.2.4.RELEASE]
        at org.apache.catalina.core.StandardContext.listenerStart(StandardContext.java:4813) [catalina.jar:8.0.35]
        at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5272) [catalina.jar:8.0.35]
        at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:147) [catalina.jar:8.0.35]
        at org.apache.catalina.core.ContainerBase.addChildInternal(ContainerBase.java:725) [catalina.jar:8.0.35]
        at org.apache.catalina.core.ContainerBase.addChild(ContainerBase.java:701) [catalina.jar:8.0.35]
        at org.apache.catalina.core.StandardHost.addChild(StandardHost.java:717) [catalina.jar:8.0.35]
        at org.apache.catalina.startup.HostConfig.deployWAR(HostConfig.java:940) [catalina.jar:8.0.35]
        at org.apache.catalina.startup.HostConfig$DeployWar.run(HostConfig.java:1816) [catalina.jar:8.0.35]
        at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511) [na:1.8.0_77]
        at java.util.concurrent.FutureTask.run(FutureTask.java:266) [na:1.8.0_77]
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) [na:1.8.0_77]
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) [na:1.8.0_77]
        at java.lang.Thread.run(Thread.java:745) [na:1.8.0_77]

環境

  • PostgreSQL 9.4.5
  • PostgreSQL JDBC Driver postgresql-9.4.1208.jar
  • Hibernate 4.3.11
  • OpenJDK 1.8.0.91

スタックトレースからわかること

JDBCのcreateClob APIを実行してSQLFeatureNotSupportedExceptionが発生しています。
PostgreSQLにはCLOB型は無いので、妥当といえば妥当です。

PostgreSQL JDBC Driverのソースコード

以下のように、createClog()が呼ばれるとSQLFeatureNotSupportedExceptionが投げられるようになっています。

org.postgresql.jdbc.PgConnection.java
  public Clob createClob() throws SQLException {
    checkClosed();
    throw org.postgresql.Driver.notImplemented(this.getClass(), "createClob()");
  }
org.postgresql.Driver.java
  public static SQLFeatureNotSupportedException notImplemented(Class<?> callClass,
      String functionName) {
    return new SQLFeatureNotSupportedException(
        GT.tr("Method {0} is not yet implemented.", callClass.getName() + "." + functionName),
        PSQLState.NOT_IMPLEMENTED.getState());
  }

Hibernateのソースコード

どうやらJDBC接続の初期化時に、JDBC APIが実装されているかをチェックしてフラグを立てているだけの様子。ということで、エラーになってもそのJDBC APIは使わないようになるはず。

org/hibernate/engine/jdbc/internal/LobCreatorBuilder.java
 69         /**                             
 70          * Basically here we are simply checking whether we can call the {@link Connection} methods for
 71          * LOB creation added in JDBC 4.  We not only check whether the {@link Connection} declares these methods,
 72          * but also whether the actual {@link Connection} instance implements them (i.e. can be called without simply
 73          * throwing an exception).
 74          *                      
 75          * @param jdbcConnection The connection which can be used in level-of-support testing.
 76          *              
 77          * @return True if the connection can be used to create LOBs; false otherwise.
 78          */                     
 79         @SuppressWarnings("unchecked")
 80         private static boolean useContextualLobCreation(Map configValues, Connection jdbcConnection) {
 81                 final boolean isNonContextualLobCreationRequired =
 82                                 ConfigurationHelper.getBoolean( Environment.NON_CONTEXTUAL_LOB_CREATION, configValues );
 83                 if ( isNonContextualLobCreationRequired ) {
 84                         LOG.disablingContextualLOBCreation( Environment.NON_CONTEXTUAL_LOB_CREATION );
 85                         return false;
 86                 }
 87                 if ( jdbcConnection == null ) {
 88                         LOG.disablingContextualLOBCreationSinceConnectionNull();
 89                         return false;
 90                 }
<<>>
107                         if ( createClobMethod.getDeclaringClass().equals( Connection.class ) ) {
108                                 // If we get here we are running in a jdk 1.6 (jdbc 4) environment...
109                                 // Further check to make sure the driver actually implements the LOB creation methods.  We
110                                 // check against createClob() as indicative of all; should we check against all 3 explicitly?
111                                 try {
112                                         final Object clob = createClobMethod.invoke( jdbcConnection, NO_ARGS );
113                                         try {
114                                                 final Method freeMethod = clob.getClass().getMethod( "free", NO_ARG_SIG );
115                                                 freeMethod.invoke( clob, NO_ARGS );
116                                         }
117                                         catch ( Throwable ignore ) {
118                                                 LOG.tracef( "Unable to free CLOB created to test createClob() implementation : %s",     ignore );
119                                         }
120                                         return true;
121                                 }
122                                 catch ( Throwable t ) {
123                                         LOG.disablingContextualLOBCreationSinceCreateClobFailed( t );
124                                 }
125                         }
126                 }
127                 catch ( NoSuchMethodException ignore ) {
128                 }
129 
130                 return false;
131         }
<<>>
org/hibernate/engine/jdbc/internal/LobCreatorBuilder.java
 56          * The public factory method for obtaining the appropriate (according to given JDBC {@link java.sql.Connection}.
 57          *                              
 58          * @param configValues The map of settings
 59          * @param jdbcConnection A JDBC {@link java.sql.Connection} which can be used to gauge the drivers level of support,
 60          * specifically for creating LOB references.
 61          */                             
 62         public LobCreatorBuilder(Map configValues, Connection jdbcConnection) {
 63                 this.useContextualLobCreation = useContextualLobCreation( configValues, jdbcConnection );
 64         } 
org/hibernate/engine/jdbc/internal/JdbcServicesImpl.java
 70 /**
 71  * Standard implementation of the {@link JdbcServices} contract
 72  *
 73  * @author Steve Ebersole
 74  */
 75 public class JdbcServicesImpl implements JdbcServices, ServiceRegistryAwareService, Configurable {
 <<>>
 91 
 92         @Override
 93         public void configure(Map configValues) {
<<>>
192                                         lobCreatorBuilder = new LobCreatorBuilder( configValues, connection );
org/hibernate/cfg/AvailableSettings.java
480         /**
481          * Should we not use contextual LOB creation (aka based on {@link java.sql.Connection#createBlob()} et al).
482          */                     
483         String NON_CONTEXTUAL_LOB_CREATION = "hibernate.jdbc.lob.non_contextual_creation";

ここまで読んでググったところ以下のページを発見!

Spring Boot でメール送信する Web アプリケーションを作る ( その3 )( Project の作成 )[かんがるーさんの日記]
http://ksby.hatenablog.com/entry/2015/04/12/113912

上記のリンク先に書かれているように
hibernate.propertiesに

hibernate.jdbc.lob.non_contextual_creation = true

と設定すると当初のエラーが出なくなりました。

以上!

13
10
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
13
10