cloud-sql-jdbc-socket-factory icon indicating copy to clipboard operation
cloud-sql-jdbc-socket-factory copied to clipboard

Use Cloud SQL Instance connection name with Hibernate EntityManagerFactory

Open raszkiewicz opened this issue 3 years ago • 9 comments

Bug Description

I'm trying to connect an old MVC Java web-app to the Cloud SQL using provided instance connection name following steps from https://github.com/GoogleCloudPlatform/cloud-sql-jdbc-socket-factory/blob/main/docs/jdbc-mysql.md using

    <dependency>
      <groupId>com.google.cloud.sql</groupId>
      <artifactId>mysql-socket-factory</artifactId>
      <version>1.6.0</version>
    </dependency>

Related part of the code looks like:

      JDBCDriverInfo driverInfo = databaseInfo.getJDBCDriverInfo();

      try {
         Map<String, String> properties = new HashMap<String, String>();
         properties.put("javax.persistence.jdbc.url", driverInfo.getJDBCUrl());
         properties.put("javax.persistence.jdbc.driver", driverInfo.getJDBCDriver());

         String username = databaseInfo.getUsername();
         if (username != null && !username.isEmpty()) {
            properties.put("javax.persistence.jdbc.user", username);
         }

         String password = databaseInfo.getPassword();
         if (password != null && !password.isEmpty()) {
            properties.put("javax.persistence.jdbc.password", password);
         }

         EntityManagerFactory factory = Persistence.createEntityManagerFactory("AppPU", properties);
         DBFactoryInfo factoryInfo = new DBFactoryInfo(factory);
         dbFactories.put(databaseInfo.getDatasource(), factoryInfo);

         String message = "Created EntityManagerFactory for " + databaseInfo.getDatasource() + ", user " + databaseInfo.getUsername() + ", at "
               + driverInfo.getJDBCUrl() + ".";
         Logger.log(JPAUtils.class, Level.INFO, message);
      }

where

   public MySQLDriverInfo(String ip, String schema) {
      this.ip = ip;
      this.schema = schema;
   }

   @Override
   public String getJDBCDriver() {
      String jdbcDriver = "com.mysql.jdbc.Driver";
      return jdbcDriver;
   }

   @Override
   public String getJDBCUrl() {
      //String dbUrl = "jdbc:mysql:///<DATABASE_NAME>?cloudSqlInstance=<INSTANCE_CONNECTION_NAME>&socketFactory=com.google.cloud.sql.mysql.SocketFactory&user=<MYSQL_USER_NAME>&password=<MYSQL_USER_PASSWORD>"
      String dbUrl = "jdbc:mysql:///my_db?cloudSqlInstance=test:us-east4:cloud-sql&socketFactory=com.google.cloud.sql.mysql.SocketFactory&user=me&password=*****";
      return dbUrl;
   }

Stacktrace

but that will fail to create Persistence.createEntityManagerFactory("AppPU", properties); as Unable to build entity manager factory. NoSuchMethodError thrown. Possible issue with database or database data: com.google.common.util.concurrent.RateLimiter.acquire(I)D

Environment

OS type and version: CentOS Linux release 7.9.2009
Java SDK version: 1.8.0_262-b10
Socket Factory version: 1.6.0

raszkiewicz avatar May 31 '22 13:05 raszkiewicz

Hi @raszkiewicz,

It's helpful if you can give us more complete information, like fully answering the questions in the bug template.

Are you sure the project doesn't use Guava, even as a downstream dependency (it's included in this library)? You can use mvn dependency:tree to fully list all the dependencies for a project.

kurtisvg avatar May 31 '22 14:05 kurtisvg

@kurtisvg

OK, it looks like Guava is used by com.google.cloud.sql:mysql-socket-factory:jar so IMO it should be embed into that dependency

OP updated with more data based on the bug template.

raszkiewicz avatar May 31 '22 16:05 raszkiewicz

@raszkiewicz can you provide us with the full stack trace - not just the top error?

kurtisvg avatar May 31 '22 17:05 kurtisvg

@kurtisvg OK, here is the app stack trace cause by the error mentioned above

com.tada.macommons.db.dao.jpa.JPATransactionException: No EntityManagerFactory exists for datasource 'defaultDatasource'.
        at com.tada.macommons.db.dao.jpa.JPATransaction.createEntityManager(JPATransaction.java:67)
        at com.tada.macommons.db.dao.jpa.JPATransaction.createEntityManager(JPATransaction.java:41)
        at com.tada.macommons.db.dao.jpa.JpaDao.getEntityManager(JpaDao.java:68)
        at com.tada.macommons.db.dao.jpa.JpaDao.findAll(JpaDao.java:264)
        at com.tada.macommons.db.dao.jpa.JpaDao.findAll(JpaDao.java:216)
        at com.tada.app.portal.service.PortalServiceManager.getAppConfigs(PortalServiceManager.java:214)
        at com.tada.macommons.app.WebAppContextListener.contextInitialized(WebAppContextListener.java:90)
        at com.tada.app.portal.PortalContextListener.contextInitialized(PortalContextListener.java:36)
        at org.apache.catalina.core.StandardContext.listenerStart(StandardContext.java:4643)
        at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5109)
        at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:183)
        at org.apache.catalina.core.ContainerBase.addChildInternal(ContainerBase.java:743)
        at org.apache.catalina.core.ContainerBase.addChild(ContainerBase.java:719)
        at org.apache.catalina.core.StandardHost.addChild(StandardHost.java:703)
        at org.apache.catalina.startup.HostConfig.deployWAR(HostConfig.java:986)
        at org.apache.catalina.startup.HostConfig$DeployWar.run(HostConfig.java:1858)
        at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
        at java.util.concurrent.FutureTask.run(FutureTask.java:266)
        at org.apache.tomcat.util.threads.InlineExecutorService.execute(InlineExecutorService.java:75)
        at java.util.concurrent.AbstractExecutorService.submit(AbstractExecutorService.java:112)
        at org.apache.catalina.startup.HostConfig.deployWARs(HostConfig.java:772)
        at org.apache.catalina.startup.HostConfig.deployApps(HostConfig.java:426)
        at org.apache.catalina.startup.HostConfig.check(HostConfig.java:1629)
        at org.apache.catalina.startup.HostConfig.lifecycleEvent(HostConfig.java:304)
        at org.apache.catalina.util.LifecycleBase.fireLifecycleEvent(LifecycleBase.java:123)
        at org.apache.catalina.core.ContainerBase.backgroundProcess(ContainerBase.java:1176)
        at org.apache.catalina.core.ContainerBase$ContainerBackgroundProcessor.processChildren(ContainerBase.java:1398)
        at org.apache.catalina.core.ContainerBase$ContainerBackgroundProcessor.processChildren(ContainerBase.java:1402)
        at org.apache.catalina.core.ContainerBase$ContainerBackgroundProcessor.run(ContainerBase.java:1370)
        at java.lang.Thread.run(Thread.java:748)

raszkiewicz avatar May 31 '22 18:05 raszkiewicz

Is that the entire stack trace? It doesn't look like it has the section com.google.common.util.concurrent.RateLimiter.acquire(I) you mentioned before.

kurtisvg avatar May 31 '22 19:05 kurtisvg

It is stacktrace from the app. I have debugged what causes it in the createEntityManager and it was that error mentioned in the OP image

raszkiewicz avatar May 31 '22 19:05 raszkiewicz

Do you have the full stacktrace for that error? It seems like understandably, the No EntityManagerFactory exists for datasource 'defaultDatasource'. is being caused because Persistence.createEntityManagerFactory("AppPU", properties); fails. So fixing that issue should resolve the second error, but it's hard to know without more information.

Can you share a minimal reproduction of the error?

kurtisvg avatar Jun 01 '22 16:06 kurtisvg

Unfortunately the app doesn't produce stacktrace in the cataline.out for that error.

What I can see when debugging the app is javax.persistence.PersistenceException: Unable to build entity manager factory when the error occur

For validation I have switched back to use direct connection to the Cloud SQL using IP address and I did not had any issues with Persistence.createEntityManagerFactory("AppPU", properties)

raszkiewicz avatar Jun 01 '22 19:06 raszkiewicz

Unfortunately without a good way to reproduce or get more information, we're probably not going to be make much progress. it seems likely this might be a problem with your environment/project, since we haven't had anyone else report any similar issues so far.

One gut suspicion I have is that you might have a dependency conflict - if you are using Maven, you could try to use a "dependencyConvergence" rule to detect this, and then use dependencyManagement to resolve it.

kurtisvg avatar Jun 03 '22 22:06 kurtisvg

Going to close this as stale. Feel free to re-open with any additional information.

enocom avatar Nov 21 '22 21:11 enocom