cloud-sql-jdbc-socket-factory
cloud-sql-jdbc-socket-factory copied to clipboard
Use Cloud SQL Instance connection name with Hibernate EntityManagerFactory
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
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
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 can you provide us with the full stack trace - not just the top error?
@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)
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.
It is stacktrace from the app. I have debugged what causes it in the createEntityManager and it was that error mentioned in the OP

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?
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)
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.
Going to close this as stale. Feel free to re-open with any additional information.