Thread: NullPointerException in TypeInfoCache.getSQLType

NullPointerException in TypeInfoCache.getSQLType

From
Zachary Marshall
Date:

Hello,


I am running into a NullPointerException in the Postgres JDBC driver. I am running driver version postgresql-9.4.1208.jre7-SNAPSHOT.jar​. I am running against Postgres server version "PostgreSQL 9.4.5 on x86_64-unknown-linux-gnu, compiled by gcc (Ubuntu/Linaro 4.6.3-1ubuntu5) 4.6.3, 64-bit". The error occurs when I am starting up my Spring Boot application. Typically this is concurrent with the startup of several dozen other Spring Boot apps, all which use the same Postgres server, but each in an entirely different JVM. These concurrent startups all are typically creating new schemas (then tables and other things in those schemas). If the error occurs, restarting the Spring Boot app resolves it. I have searched google and the mailing list but didn't see any obvious hits (other than the mention of this revert from the 9.4-1205 changelog: https://github.com/pgjdbc/pgjdbc/pull/406). The relevant part of the stack trace is at the end of the email. One possible cause I can imagine is that org.postgresql.jdbc.TypeInfoCache.getPGType(int) returns null (because oid == Oid.UNSPECIFIED)(https://github.com/pgjdbc/pgjdbc/blob/master/pgjdbc/src/main/java/org/postgresql/jdbc/TypeInfoCache.java#L387) and then org.postgresql.jdbc.TypeInfoCache.getSQLType(String) doesn't correctly handle this null (https://github.com/pgjdbc/pgjdbc/blob/master/pgjdbc/src/main/java/org/postgresql/jdbc/TypeInfoCache.java#L182).


Has anyone seen this before? Thanks in advance for any help.​


Caused by: java.lang.NullPointerException
at org.postgresql.jdbc.TypeInfoCache.getSQLType(TypeInfoCache.java:182)
at org.postgresql.jdbc.TypeInfoCache.getSQLType(TypeInfoCache.java:178)
at org.postgresql.jdbc.TypeInfoCache.requiresQuoting(TypeInfoCache.java:851)
at org.postgresql.jdbc.PgDatabaseMetaData.getTypeInfo(PgDatabaseMetaData.java:2785)
at org.hibernate.engine.jdbc.spi.TypeInfo.extractTypeInfo(TypeInfo.java:101)
at org.hibernate.engine.jdbc.internal.JdbcServicesImpl.configure(JdbcServicesImpl.java:163)
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:1887)
at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:1845)
at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl$4.perform(EntityManagerFactoryBuilderImpl.java:857)
at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl$4.perform(EntityManagerFactoryBuilderImpl.java:850)
at org.hibernate.boot.registry.classloading.internal.ClassLoaderServiceImpl.withTccl(ClassLoaderServiceImpl.java:425)
at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.build(EntityManagerFactoryBuilderImpl.java:849)
at org.springframework.orm.jpa.vendor.SpringHibernateJpaPersistenceProvider.createContainerEntityManagerFactory(SpringHibernateJpaPersistenceProvider.java:60)
at org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean.createNativeEntityManagerFactory(LocalContainerEntityManagerFactoryBean.java:343)
at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.afterPropertiesSet(AbstractEntityManagerFactoryBean.java:318)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1637)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1574)
... 22 more


Re: NullPointerException in TypeInfoCache.getSQLType

From
Vladimir Sitnikov
Date:
Do you have a reproducer?

Can you check if you have types with typname of null?
select * from pg_catalog.pg_type t where t.typname is null

>  all are typically creating new schemas

Can it be like:
1) org.postgresql.jdbc.PgDatabaseMetaData#getTypeInfo loads all the type ids
2) as it reaches org.postgresql.jdbc.TypeInfoCache#getPGType(int), the
type is no longer in the DB (e.g. dropped)
?

Can you add logging to TypeInfoCache#getPGType & rebuild & test to log
the actual oid in question?

Vladimir


Re: NullPointerException in TypeInfoCache.getSQLType

From
Vladimir Sitnikov
Date:
>It will be hard to supply a reproducer since it seems to require lots of concurrent startups

Blind guess would be: a two-threaded test.
Thread 1: create & drop table in a loop
Thread 2: PgDatabaseMetaData.getTypeInfo & clear cache in a loop

>Your explanation seems plausible. I will add the suggested logging

That would be awesome.


Vladimir


Re: NullPointerException in TypeInfoCache.getSQLType

From
Zachary Marshall
Date:
It will be hard to supply a reproducer since it seems to require lots of concurrent startups, but I will see if I can
simplifythe reproducible case.
 

Your explanation seems plausible. I will add the suggested logging and rebuild and test to log the oid and other
information.It will probably be a few days before I have those results.
 

Thanks for your suggestions and time,
Zach Marshall

-----Original Message-----
From: Vladimir Sitnikov [mailto:sitnikov.vladimir@gmail.com] 
Sent: Wednesday, February 17, 2016 9:20 AM
To: Zachary Marshall <Zachary.Marshall@sas.com>
Cc: pgsql-jdbc@postgresql.org
Subject: Re: [JDBC] NullPointerException in TypeInfoCache.getSQLType

Do you have a reproducer?

Can you check if you have types with typname of null?
select * from pg_catalog.pg_type t where t.typname is null

>  all are typically creating new schemas

Can it be like:
1) org.postgresql.jdbc.PgDatabaseMetaData#getTypeInfo loads all the type ids
2) as it reaches org.postgresql.jdbc.TypeInfoCache#getPGType(int), the type is no longer in the DB (e.g. dropped) ?

Can you add logging to TypeInfoCache#getPGType & rebuild & test to log the actual oid in question?

Vladimir

Re: NullPointerException in TypeInfoCache.getSQLType

From
Zachary Marshall
Date:
It will be hard to supply a reproducer since it seems to require lots of concurrent startups, but I will see if I can
simplifythe reproducible case.
 

Your explanation seems plausible. I will add the suggested logging and rebuild and test to log the oid and other
information.It will probably be a few days before I have those results.
 

Thanks for your suggestions and time,
Zach Marshall

-----Original Message-----
From: Vladimir Sitnikov [mailto:sitnikov.vladimir@gmail.com] 
Sent: Wednesday, February 17, 2016 9:20 AM
To: Zachary Marshall <Zachary.Marshall@sas.com>
Cc: pgsql-jdbc@postgresql.org
Subject: Re: [JDBC] NullPointerException in TypeInfoCache.getSQLType

Do you have a reproducer?

Can you check if you have types with typname of null?
select * from pg_catalog.pg_type t where t.typname is null

>  all are typically creating new schemas

Can it be like:
1) org.postgresql.jdbc.PgDatabaseMetaData#getTypeInfo loads all the type ids
2) as it reaches org.postgresql.jdbc.TypeInfoCache#getPGType(int), the type is no longer in the DB (e.g. dropped) ?

Can you add logging to TypeInfoCache#getPGType & rebuild & test to log the actual oid in question?

Vladimir

Re: NullPointerException in TypeInfoCache.getSQLType

From
Stephanie Smith
Date:
Vladimir
I am able to reproduce the NullPointerException with a standalone test.
I have created the following repository with the test case, https://github.com/stephraleigh/postgres-jdbc-npe-rep

Please let me know if you are able to clone and reproduce the NPE.
Thanks
Steph


-----Original Message-----
From: Vladimir Sitnikov [mailto:sitnikov.vladimir@gmail.com] 
Sent: Wednesday, February 17, 2016 9:50 AM
To: Zachary Marshall <Zachary.Marshall@sas.com>
Cc: pgsql-jdbc@postgresql.org
Subject: Re: [JDBC] NullPointerException in TypeInfoCache.getSQLType

>It will be hard to supply a reproducer since it seems to require lots of concurrent startups

Blind guess would be: a two-threaded test.
Thread 1: create & drop table in a loop
Thread 2: PgDatabaseMetaData.getTypeInfo & clear cache in a loop

>Your explanation seems plausible. I will add the suggested logging

That would be awesome.


Vladimir

Re: NullPointerException in TypeInfoCache.getSQLType

From
Vladimir Sitnikov
Date:
Thanks for the reproducer.
I've implemented a fix here: https://github.com/pgjdbc/pgjdbc/pull/530

There are other similar places when type information is loaded by
using several queries.
For example: getProcedureColumns, however it is likely to be used with
some reasonable
schema/procedure patterns, thus it is less likely to fail.

Vladimir


Re: NullPointerException in TypeInfoCache.getSQLType

From
Stephanie Smith
Date:
Vladimir
I am able to reproduce the NullPointerException with a standalone test.
I have created the following repository with the test case, https://github.com/stephraleigh/postgres-jdbc-npe-rep

Please let me know if you are able to clone and reproduce the NPE.
Thanks
Steph


-----Original Message-----
From: Vladimir Sitnikov [mailto:sitnikov.vladimir@gmail.com] 
Sent: Wednesday, February 17, 2016 9:50 AM
To: Zachary Marshall <Zachary.Marshall@sas.com>
Cc: pgsql-jdbc@postgresql.org
Subject: Re: [JDBC] NullPointerException in TypeInfoCache.getSQLType

>It will be hard to supply a reproducer since it seems to require lots of concurrent startups

Blind guess would be: a two-threaded test.
Thread 1: create & drop table in a loop
Thread 2: PgDatabaseMetaData.getTypeInfo & clear cache in a loop

>Your explanation seems plausible. I will add the suggested logging

That would be awesome.


Vladimir

Re: NullPointerException in TypeInfoCache.getSQLType

From
Vladimir Sitnikov
Date:
Thanks for the reproducer.
I've implemented a fix here: https://github.com/pgjdbc/pgjdbc/pull/530

There are other similar places when type information is loaded by
using several queries.
For example: getProcedureColumns, however it is likely to be used with
some reasonable
schema/procedure patterns, thus it is less likely to fail.

Vladimir