[keycloak-user] org.hibernate.LazyInitializationException (could not initialize proxy - no Session) when getting user attributes

Ilya Korol llivezking at gmail.com
Tue Nov 21 19:20:36 EST 2017


Hi. I've wrote some implementation of org.keycloak.timer.ScheduledTask 
that should periodically conditionally delete some users, depending on 
their attribute values:

     @Override
     public void run(KeycloakSession session) {
         long currentTime = 
TimeUnit.MILLISECONDS.toSeconds(Time.currentTimeMillis());

         RealmModel realm;     // appropriate realm was set
         GroupModel group;     // appropriate group was set
         session.userLocalStorage()
                             .getGroupMembers(realm, group).stream()
                             .filter(user -> isNotVerified(user) && 
isExpired(user, currentTime))
                             .forEach(user -> {
session.userLocalStorage().removeUser(realm, user);
                             });
     }

     private boolean isNotVerified(UserModel user) {
             return user.getFirstAttribute(UserAttributes.STATUS) != null
                     && 
user.getFirstAttribute(UserAttributes.STATUS).equals(UserStatuses.NOT_VERIFIED);
     }

     private boolean isExpired(UserModel user, long currentTime) {
         return 
TimeUnit.MILLISECONDS.toSeconds(user.getCreatedTimestamp()) + 
expirationTimeout < currentTime;
     }


When it runs i got following exception in method isNotVerified(UserModel 
user) for users that don't have any attributes. (For users with any 
attributes this will work)


2017-11-21 14:51:31,030 ERROR [org.keycloak.services] (Timer-2) 
KC-SERVICES0089: Failed to run scheduled task 
ClearExpiredOnboardingUsers: org.hibernate.LazyInitializationException: 
failed to lazily initialize a collection of role: 
org.keycloak.models.jpa.entities.UserEntity.attributes, could not 
initialize proxy - no Session
         at 
org.hibernate.collection.internal.AbstractPersistentCollection.throwLazyInitializationException(AbstractPersistentCollection.java:567)
         at 
org.hibernate.collection.internal.AbstractPersistentCollection.withTemporarySessionIfNeeded(AbstractPersistentCollection.java:205)
         at 
org.hibernate.collection.internal.AbstractPersistentCollection.initialize(AbstractPersistentCollection.java:546)
         at 
org.hibernate.collection.internal.AbstractPersistentCollection.read(AbstractPersistentCollection.java:133)
         at 
org.hibernate.collection.internal.PersistentBag.iterator(PersistentBag.java:277)
         at 
org.keycloak.models.jpa.UserAdapter.getFirstAttribute(UserAdapter.java:176)
         at 
company.utils.ClearExpiredOnboardingUsers.isNotVerified(ClearExpiredOnboardingUsers.java:50)
         at 
company.utils.ClearExpiredOnboardingUsers.lambda$run$0(ClearExpiredOnboardingUsers.java:41)
         at 
java.util.stream.ReferencePipeline$2$1.accept(ReferencePipeline.java:174)
         at 
java.util.ArrayList$ArrayListSpliterator.forEachRemaining(ArrayList.java:1380)
         at 
java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:481)
         at 
java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:471)
         at 
java.util.stream.ForEachOps$ForEachOp.evaluateSequential(ForEachOps.java:151)
         at 
java.util.stream.ForEachOps$ForEachOp$OfRef.evaluateSequential(ForEachOps.java:174)
         at 
java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234)
         at 
java.util.stream.ReferencePipeline.forEach(ReferencePipeline.java:418)
         at 
company.utils.ClearExpiredOnboardingUsers.run(ClearExpiredOnboardingUsers.java:42)
         at 
org.keycloak.services.scheduled.ScheduledTaskRunner.runTask(ScheduledTaskRunner.java:61)
         at 
org.keycloak.services.scheduled.ScheduledTaskRunner.run(ScheduledTaskRunner.java:45)
         at 
org.keycloak.timer.basic.BasicTimerProvider$1.run(BasicTimerProvider.java:51)
         at java.util.TimerThread.mainLoop(Timer.java:555)
         at java.util.TimerThread.run(Timer.java:505)


I found a workaround by surrounding attributes verification with 
try/catch RuntimeException. In debugger i checked that 
session.getTransactionManager.isActive() returns true. So i'm 
interesting in possible problems here. Do i have any mistakes in my code 
or there is a some kind of bug? Should it be moved to Jira?



More information about the keycloak-user mailing list