[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