Come ho commentato prima, è perché i socket aperti e collegati al database non si rendono conto che la connessione è stata persa, quindi sono rimasti collegati fino a quando non viene attivato il timeout del socket del sistema operativo, che ho letto potrebbe essere di solito in circa 30 minuti .
Per risolvere il problema è necessario sovrascrivere il timeout del socket nella stringa di connessione JDBC o nella configurazione/proprietà della connessione JDNI per definire il socketTimeout param a un tempo inferiore.
Tieni presente che qualsiasi connessione più lunga del valore definito verrà uccisa, anche se viene utilizzata (non sono stato in grado di confermarlo, è quello che ho letto).
Gli altri due parametri che menziono nel mio commento sono connectTimeout e Riconnessione automatica .
Ecco la mia stringa di connessione JDBC:
jdbc:(...)&connectTimeout=15000&socketTimeout=60000&autoReconnect=true
Ho anche disabilitato la cache DNS di Java facendo
java.security.Security.setProperty("networkaddress.cache.ttl" , "0");
java.security.Security.setProperty("networkaddress.cache.negative.ttl" , "0");
Lo faccio perché Java non rispetta i TTL e quando si verifica il failover, il DNS è lo stesso ma l'IP cambia.
Poiché stai utilizzando un server delle applicazioni, i parametri per disabilitare la cache DNS devono essere passati alla JVM all'avvio di glassfish con -Dnet e non l'applicazione stessa.