I am trying to execute a stupid query from @Scheduled
method using an ApplicationScoped
PanacheRepository
@ApplicationScoped
public class MyRepo implements PanacheRepository<MyEntity> {
then I have the following
@Inject
MyRepo repo;
@Scheduled(every = "${cache.refreshRate}", delayed = "20s")
public Uni<Void> scheduleRefresh() {
return repo.listAll().replaceWithVoid();
}
And I am getting the following exception
(vert.x-eventloop-thread-0) Error occurred while executing task for trigger IntervalTrigger [id=1_org.xx.xxxxx.infrastructure.importer.Importer_ScheduledInvoker_scheduleRefresh_520a27e95be32ee7cfd3163651929119f1ff17fe, interval=300000]: java.lang.IllegalStateException: Session/EntityManager is closed at org.hibernate.internal.AbstractSharedSessionContract.checkOpen(AbstractSharedSessionContract.java:407) at org.hibernate.engine.spi.SharedSessionContractImplementor.checkOpen(SharedSessionContractImplementor.java:148) at org.hibernate.reactive.session.impl.ReactiveSessionImpl.checkOpen(ReactiveSessionImpl.java:1558) at org.hibernate.internal.AbstractSharedSessionContract.checkOpenOrWaitingForAutoClose(AbstractSharedSessionContract.java:413) at
EDIT
The application runs correctly locally (postgres on docker) but fails on the cloud (gcp + cloudsql)
I think this is a bug in Quarkus.
This workaround should work:
@ApplicationScoped
public class SchedulerBean {
@Inject
Mutiny.SessionFactory factory;
@Scheduled(every = "${cache.refreshRate}", delayed = "20s")
Uni<Void> scheduleRefresh() {
return factory.withSession( SchedulerBean::refresh );
}
private static Uni<Void> refresh(Mutiny.Session s) {
return s.createQuery( "from MyEntity" ).getResultList().replaceWithVoid();
}
}
You can rewrite it with criteria, if you prefer something programmatic:
private static Uni<Void> refresh(Mutiny.Session s) {
CriteriaQuery<MyEntity> query = factory
.getCriteriaBuilder()
.createQuery( MyEntity.class );
query.from( MyEntity.class );
return s.createQuery( query ).getResultList().replaceWithVoid();
}