I have a Spring Boot project which mostly uses Repository's for all db operations, however I have a table that is not backed by an entity and thus doesn't use a Repository. Instead I use an EntityManager and run a native query.
This works well most of the time, but every so often (but often enough that it's noticeable), the query just fails for seemingly no reason.
Here's my code:
@RequiredArgsConstructor
public class AddChangeRequest {
@Qualifier("a-entity-manager")
private final EntityManager entityManager;
public void of(G g, P p) {
entityManager.joinTransaction();
entityManager.createNativeQuery(
"INSERT INTO CHANGE_REQUESTS (P_ID, G_PK) VALUES (?,?) ON CONFLICT (P_ID) DO UPDATE SET LAST_CHANGE_DATE = NOW()")
.setParameter(1, p.getPId())
.setParameter(2, g.getGPk())
.executeUpdate();
}
One thing to note here is that I have two EntityManagers in my project.
One a-entity-manager
which is defined as so:
@Bean
@Qualifier("a-entity-manager")
public EntityManager entityManager(EntityManagerFactory entityManagerFactory) {
return entityManagerFactory.createEntityManager();
}
And another which is brought in from another project in my pom file and by scanning for the package it's in:
@SpringBootApplication(scanBasePackages=....
The error that I sometimes get typically looks something like (usually there's a few different errors back to back):
o.h.engine.jdbc.spi.SqlExceptionHelper : This statement has been closed.
org.hibernate.exception.GenericJDBCException: could not execute statement
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.spi.SqlExceptionHelper.convert(SqlExceptionHelper.java:99)
at org.hibernate.engine.jdbc.internal.ResultSetReturnImpl.executeUpdate(ResultSetReturnImpl.java:200)
at org.hibernate.engine.query.spi.NativeSQLQueryPlan.performExecuteUpdate(NativeSQLQueryPlan.java:107)
at org.hibernate.internal.SessionImpl.executeNativeUpdate(SessionImpl.java:1491)
at org.hibernate.query.internal.NativeQueryImpl.doExecuteUpdate(NativeQueryImpl.java:295)
at org.hibernate.query.internal.AbstractProducedQuery.executeUpdate(AbstractProducedQuery.java:1605)
org.postgresql.util.PSQLException: This statement has been closed.
at org.postgresql.jdbc.PgStatement.checkClosed(PgStatement.java:694)
at org.postgresql.jdbc.PgStatement.executeInternal(PgStatement.java:447)
at org.postgresql.jdbc.PgStatement.execute(PgStatement.java:365)
at org.postgresql.jdbc.PgPreparedStatement.executeWithFlags(PgPreparedStatement.java:143)
at org.postgresql.jdbc.PgPreparedStatement.executeUpdate(PgPreparedStatement.java:120)
at com.zaxxer.hikari.pool.ProxyPreparedStatement.executeUpdate(ProxyPreparedStatement.java:61)
at com.zaxxer.hikari.pool.HikariProxyPreparedStatement.executeUpdate(HikariProxyPreparedStatement.java)
at org.hibernate.engine.jdbc.internal.ResultSetReturnImpl.executeUpdate(ResultSetReturnImpl.java:197)
at org.hibernate.engine.query.spi.NativeSQLQueryPlan.performExecuteUpdate(NativeSQLQueryPlan.java:107)
at org.hibernate.internal.SessionImpl.executeNativeUpdate(SessionImpl.java:1491)
at org.hibernate.query.internal.NativeQueryImpl.doExecuteUpdate(NativeQueryImpl.java:295)
at org.hibernate.query.internal.AbstractProducedQuery.executeUpdate(AbstractProducedQuery.java:1605)
The last thing to note is that when this code is run it's as a result of a network call and there's usually a fair number of requests made in quick succession. Probably on average 10-50 calls.
Anyone have any ideas what could be going on here? I believe it may have something to do with having multiple EntityManagers because that is rather new and I don't think this happened before. Before this rather recent change this code was just using the "default" EntityManager, I didn't define my own at all.
Thanks!