Skip to content

Spanner JDBC driver checks and fails hard when unknown properties provided #6671

@saturnism

Description

@saturnism

Environment details

  1. google-cloud-spanner-jdbc 1.7.0
  2. OS type and version: osx
  3. Java version: openjdk 11
  4. google-cloud-java version(s): 1.7..0

Steps to reproduce

  1. Create a Quarkus app
  2. Use JPA w/ Hibernate and Spanner JDBC driver

Code example

persistence.xml

<persistence xmlns="http://xmlns.jcp.org/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence
http://xmlns.jcp.org/xml/ns/persistence/persistence_2_1.xsd"
             version="2.1">
    <persistence-unit name="spanner-example">
        <provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>

        <class>Person</class>

        <properties>
            <property name="javax.persistence.jdbc.url" value="jdbc:cloudspanner:/projects/wise-coyote-827/instances/demo/databases/demo" />
            <property name="javax.persistence.jdbc.driver" value="com.google.cloud.spanner.jdbc.JdbcDriver" />
            <property name="javax.persistence.jdbc.user" value="" />
            <property name="javax.persistence.jdbc.password" value="" />
            <property name="hibernate.dialect" value="com.google.cloud.spanner.hibernate.SpannerDialect"/>
            <property name="hibernate.connection.autocommit" value="true" />
            <property name="hibernate.hbm2ddl.auto" value="create-drop"/>
            <property name="show_sql" value="true"/>
        </properties>
    </persistence-unit>
</persistence>

This is reproducible in non-quarkus environment (e.g., Thorntail) by adding:

   <property name="hibernate.connection.provider_disables_autocommit" value="true"/>
@Entity
public class Person {
	@GeneratedValue(strategy = GenerationType.AUTO)
	@Type(type="uuid-char")
	@Id
	private UUID id;
	private String name;

	public UUID getId() {
		return id;
	}

	public void setId(UUID id) {
		this.id = id;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}
}
@Path("/hi")
public class Say {

    @Inject EntityManager em;

    @GET
    @Produces(MediaType.TEXT_PLAIN)
    public String hello() {
        Person p = new Person();
        p.setName("Ray");
        em.persist(p);
        return "hello there";
    }
}

Stack trace

2019-10-31 17:45:22,186 WARN  [org.hib.orm.con.pooling] (main) HHH10001002: Using Hibernate built-in connection pool (not for production use!)
2019-10-31 17:45:22,188 INFO  [org.hib.orm.con.pooling] (main) HHH10001005: using driver [com.google.cloud.spanner.jdbc.JdbcDriver] at URL [jdbc:cloudspanner:/projects/wise-coyote-827/instances/demo/databases/demo]
2019-10-31 17:45:22,189 INFO  [org.hib.orm.con.pooling] (main) HHH10001001: Connection properties: {autocommit=true, provider_disables_autocommit=true}
2019-10-31 17:45:22,189 INFO  [org.hib.orm.con.pooling] (main) HHH10001003: Autocommit mode: true
2019-10-31 17:45:22,190 INFO  [org.hib.eng.jdb.con.int.DriverManagerConnectionProviderImpl] (main) HHH000115: Hibernate connection pool size: 20 (min=1)
2019-10-31 17:45:22,210 WARN  [org.hib.eng.jdb.spi.SqlExceptionHelper] (main) SQL Error: 3, SQLState: null
2019-10-31 17:45:22,210 ERROR [org.hib.eng.jdb.spi.SqlExceptionHelper] (main) INVALID_ARGUMENT: Invalid properties found in connection URI: provider_disables_autocommit
2019-10-31 17:45:22,214 INFO  [org.hib.ser.int.AbstractServiceRegistryImpl] (main) HHH000369: Error stopping service [class org.hibernate.engine.jdbc.connections.internal.DriverManagerConnectionProviderImpl]: java.lang.NullPointerException
	at org.hibernate.engine.jdbc.connections.internal.DriverManagerConnectionProviderImpl.stop(DriverManagerConnectionProviderImpl.java:207)
	at org.hibernate.service.internal.AbstractServiceRegistryImpl.stopService(AbstractServiceRegistryImpl.java:390)
	at org.hibernate.service.internal.AbstractServiceRegistryImpl.destroy(AbstractServiceRegistryImpl.java:373)
	at org.hibernate.service.internal.SessionFactoryServiceRegistryImpl.destroy(SessionFactoryServiceRegistryImpl.java:103)
	at io.quarkus.hibernate.orm.runtime.boot.FastBootEntityManagerFactoryBuilder$ServiceRegistryCloser.sessionFactoryClosed(FastBootEntityManagerFactoryBuilder.java:168)
	at org.hibernate.internal.SessionFactoryObserverChain.sessionFactoryClosed(SessionFactoryObserverChain.java:61)
	at org.hibernate.internal.SessionFactoryImpl.close(SessionFactoryImpl.java:824)
	at org.hibernate.internal.SessionFactoryImpl.<init>(SessionFactoryImpl.java:404)
	at org.hibernate.boot.internal.SessionFactoryBuilderImpl.build(SessionFactoryBuilderImpl.java:462)
	at io.quarkus.hibernate.orm.runtime.boot.FastBootEntityManagerFactoryBuilder.build(FastBootEntityManagerFactoryBuilder.java:65)
	at io.quarkus.hibernate.orm.runtime.FastBootHibernatePersistenceProvider.createEntityManagerFactory(FastBootHibernatePersistenceProvider.java:54)
	at javax.persistence.Persistence.createEntityManagerFactory(Persistence.java:80)
	at javax.persistence.Persistence.createEntityManagerFactory(Persistence.java:55)
	at io.quarkus.hibernate.orm.runtime.JPAConfig$LazyPersistenceUnit.get(JPAConfig.java:109)
	at io.quarkus.hibernate.orm.runtime.JPAConfig.startAll(JPAConfig.java:57)
	at io.quarkus.hibernate.orm.runtime.HibernateOrmRecorder.startAllPersistenceUnits(HibernateOrmRecorder.java:77)
	at io.quarkus.deployment.steps.HibernateOrmProcessor$startPersistenceUnits26.deploy_0(HibernateOrmProcessor$startPersistenceUnits26.zig:70)
	at io.quarkus.deployment.steps.HibernateOrmProcessor$startPersistenceUnits26.deploy(HibernateOrmProcessor$startPersistenceUnits26.zig:36)
	at io.quarkus.runner.ApplicationImpl1.doStart(ApplicationImpl1.zig:121)
	at io.quarkus.runtime.Application.start(Application.java:94)
	at io.quarkus.runner.RuntimeRunner.run(RuntimeRunner.java:143)
	at io.quarkus.dev.DevModeMain.doStart(DevModeMain.java:176)
	at io.quarkus.dev.DevModeMain.start(DevModeMain.java:94)
	at io.quarkus.dev.DevModeMain.main(DevModeMain.java:66)

javax.persistence.PersistenceException: [PersistenceUnit: spanner-example] Unable to build Hibernate SessionFactory
	at io.quarkus.hibernate.orm.runtime.boot.FastBootEntityManagerFactoryBuilder.persistenceException(FastBootEntityManagerFactoryBuilder.java:113)
	at io.quarkus.hibernate.orm.runtime.boot.FastBootEntityManagerFactoryBuilder.build(FastBootEntityManagerFactoryBuilder.java:67)
	at io.quarkus.hibernate.orm.runtime.FastBootHibernatePersistenceProvider.createEntityManagerFactory(FastBootHibernatePersistenceProvider.java:54)
	at javax.persistence.Persistence.createEntityManagerFactory(Persistence.java:80)
	at javax.persistence.Persistence.createEntityManagerFactory(Persistence.java:55)
	at io.quarkus.hibernate.orm.runtime.JPAConfig$LazyPersistenceUnit.get(JPAConfig.java:109)
	at io.quarkus.hibernate.orm.runtime.JPAConfig.startAll(JPAConfig.java:57)
	at io.quarkus.hibernate.orm.runtime.HibernateOrmRecorder.startAllPersistenceUnits(HibernateOrmRecorder.java:77)
	at io.quarkus.deployment.steps.HibernateOrmProcessor$startPersistenceUnits26.deploy_0(HibernateOrmProcessor$startPersistenceUnits26.zig:70)
	at io.quarkus.deployment.steps.HibernateOrmProcessor$startPersistenceUnits26.deploy(HibernateOrmProcessor$startPersistenceUnits26.zig:36)
	at io.quarkus.runner.ApplicationImpl1.doStart(ApplicationImpl1.zig:121)
	at io.quarkus.runtime.Application.start(Application.java:94)
	at io.quarkus.runner.RuntimeRunner.run(RuntimeRunner.java:143)
	at io.quarkus.dev.DevModeMain.doStart(DevModeMain.java:176)
	at io.quarkus.dev.DevModeMain.start(DevModeMain.java:94)
	at io.quarkus.dev.DevModeMain.main(DevModeMain.java:66)
Caused by: org.hibernate.exception.GenericJDBCException: Error calling Driver#connect
	at org.hibernate.exception.internal.StandardSQLExceptionConverter.convert(StandardSQLExceptionConverter.java:47)
	at org.hibernate.engine.jdbc.spi.SqlExceptionHelper.convert(SqlExceptionHelper.java:113)
	at org.hibernate.engine.jdbc.connections.internal.BasicConnectionCreator.convertSqlException(BasicConnectionCreator.java:118)
	at org.hibernate.engine.jdbc.connections.internal.DriverConnectionCreator.makeConnection(DriverConnectionCreator.java:41)
	at org.hibernate.engine.jdbc.connections.internal.BasicConnectionCreator.createConnection(BasicConnectionCreator.java:58)
	at org.hibernate.engine.jdbc.connections.internal.DriverManagerConnectionProviderImpl$PooledConnections.addConnections(DriverManagerConnectionProviderImpl.java:321)
	at org.hibernate.engine.jdbc.connections.internal.DriverManagerConnectionProviderImpl$PooledConnections.<init>(DriverManagerConnectionProviderImpl.java:240)
	at org.hibernate.engine.jdbc.connections.internal.DriverManagerConnectionProviderImpl$PooledConnections.<init>(DriverManagerConnectionProviderImpl.java:218)
	at org.hibernate.engine.jdbc.connections.internal.DriverManagerConnectionProviderImpl$PooledConnections$Builder.build(DriverManagerConnectionProviderImpl.java:359)
	at org.hibernate.engine.jdbc.connections.internal.DriverManagerConnectionProviderImpl.buildPool(DriverManagerConnectionProviderImpl.java:98)
	at org.hibernate.engine.jdbc.connections.internal.DriverManagerConnectionProviderImpl.configure(DriverManagerConnectionProviderImpl.java:73)
	at org.hibernate.boot.registry.internal.StandardServiceRegistryImpl.configureService(StandardServiceRegistryImpl.java:107)
	at org.hibernate.service.internal.AbstractServiceRegistryImpl.initializeService(AbstractServiceRegistryImpl.java:246)
	at org.hibernate.service.internal.AbstractServiceRegistryImpl.getService(AbstractServiceRegistryImpl.java:214)
	at org.hibernate.service.internal.SessionFactoryServiceRegistryImpl.getService(SessionFactoryServiceRegistryImpl.java:98)
	at org.hibernate.internal.SessionFactoryImpl.buildLocalConnectionAccess(SessionFactoryImpl.java:478)
	at org.hibernate.internal.SessionFactoryImpl.<init>(SessionFactoryImpl.java:315)
	at org.hibernate.boot.internal.SessionFactoryBuilderImpl.build(SessionFactoryBuilderImpl.java:462)
	at io.quarkus.hibernate.orm.runtime.boot.FastBootEntityManagerFactoryBuilder.build(FastBootEntityManagerFactoryBuilder.java:65)
	... 14 more
Caused by: com.google.cloud.spanner.jdbc.JdbcSqlExceptionFactory$JdbcSqlExceptionImpl: INVALID_ARGUMENT: Invalid properties found in connection URI: provider_disables_autocommit
	at com.google.cloud.spanner.jdbc.JdbcSqlExceptionFactory.of(JdbcSqlExceptionFactory.java:296)
	at com.google.cloud.spanner.jdbc.JdbcDriver.connect(JdbcDriver.java:170)
	at org.hibernate.engine.jdbc.connections.internal.DriverConnectionCreator.makeConnection(DriverConnectionCreator.java:38)
	... 29 more
Caused by: java.lang.IllegalArgumentException: Invalid properties found in connection URI: provider_disables_autocommit
	at com.google.common.base.Preconditions.checkArgument(Preconditions.java:141)
	at com.google.cloud.spanner.jdbc.ConnectionOptions.checkValidProperties(ConnectionOptions.java:482)
	at com.google.cloud.spanner.jdbc.ConnectionOptions$Builder.setUri(ConnectionOptions.java:285)
	at com.google.cloud.spanner.jdbc.JdbcDriver.connect(JdbcDriver.java:164)
	... 30 more

External references such as API reference guides used

  • ?

Any additional information below

/cc @meltsufin @olavloite

Metadata

Metadata

Assignees

Labels

api: spannerIssues related to the Spanner API.type: feature request‘Nice-to-have’ improvement, new feature or different behavior or design.

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions