org.hibernate.LazyInitializationException: failed to lazily initialize a collection of role: sailpoint.object.Identity.links, could not initialize proxy - no Session
The provisioning request executes successfully through the AfterProvisioningRule stage. However, immediately after the rule execution completes and before the workflow reaches the Finalize step, the process fails with the above Hibernate LazyInitializationException.
The exception indicates that SailPoint is attempting to access the lazy-loaded collection: Identity.links
Observed Behavior
Provisioning workflow starts successfully.
Provisioning actions are executed on the target application.
The configured AfterProvisioningRule completes execution.
During the transition from AfterProvisioningRule to the Finalize step, the workflow throws:
org.hibernate.LazyInitializationException:
Hi @ManikantaMattaparthi - Look at your workflow to see if you are dechaching like @naveenkumar3 mentioned or maybe not passing the identity data to the step that is failing. That error means the WF does not have the identity data to look up the links.
Property crestER doesn’t exist on sailpoint.object.Identity — it’s a typo/invalid attribute name in the filter of a Population used by one of your Identity Triggers. Hibernate can’t resolve it, throws QueryException: could not resolve property: crestER, which aborts the transaction mid-Identitizer.doTriggers() — and that session teardown is what causes the subsequent LazyInitializationException on Identity.links.
can you Find the Population with the filter referencing crestER, correct it to the right attribute name.
Provisioning completes, AfterProvisioning rule runs fine (as you saw)
The workflow proceeds to identity refresh, which calls Identitizer.doTriggers() to evaluate Identity Triggers / Lifecycle Events
One of the triggers is scoped by a Population whose filter references crestER
Hibernate attempts to construct a query against sailpoint.object.Identity for a property that does not exist QueryException: could not resolve property: crestER
This exception causes the transaction to be aborted, and the session to be torn down
The workflow proceeds to the next step, which touches identity.getLinks() a lazily loaded collection while there is no (valid) session present LazyInitializationException on Identity.links
The general rule that can be taken away from this is that when faced with LazyInitializationException, one should not attempt to debug the line that caused it. Instead, look at the previous lines in the trace until the first exception is found. This will always be the true cause.
@ManikantaMattaparthi - Looks like issue with your before provisioning rule, which is the workflower.launch(wfLaunch) call in your code in try { } catch(Exception e) { failedRolesList.add(roleValue); }. So the flow is your rule is launching a sub-workflow synchronously, sub-workflow is doing identity refresh, trigger evaluation reaches the bad Population filter (QueryException) and your catch block is catching that and adding the role to the list.
Here’s the bug: your rule builds customPlan and sets both source = "LCM" and GeneratedBySplitRule = "true". Then the rule’s entry condition is:
GeneratedBySplitRule is set but never checked anywhere. So every plan your rule generates comes back through the same rule, gets split again, launches more sub-workflows. I can see GeneratedBySplitRule=true sitting in the plan arguments in the log at three separate points, which is consistent with exactly that.
Fix:
Find and fix the crestER Population. Debug page → GroupDefinition and IdentityTrigger → search for crestER. RapidSetup trigger (the stack will show sailpoint.rapidsetup.constraint.*), so double check your RapidSetup joiner/mover/leaver trigger configs as well. Either a typo, or an extended attribute that was renamed/removed from ObjectConfig:Identity.
Add GeneratedBySplitRule to the entry condition:
if (plan != null && !"true".equals(String.valueOf(plan.getArguments().get("GeneratedBySplitRule"))) && (...source checks...))
Without this you will continue to nest sub-workflows even after crestER is fixed.
As it stands, catch(Exception e) { failedRolesList.add(roleValue); } is masking Hibernate failures and allowing you to continue on a dead session precisely what turned a (visible!) QueryException into a cryptic LazyInitializationException 16 seconds later.