call:refreshIdentity Error (Consistent)

Which IIQ version are you inquiring about?

8.3sp2

Issue Summary

Some time back, we found a bug in our workflows where the call:refreshIdentity wasn’t being called because of a faulty initialized conditional. Now that it is working, we are getting consistent errors when we do the call:refreshIdentity function. I know that this is akin to the Lazy Initialization Exception problem that occurs with Hibernate, but this case is inside a Workflow. I know how to fix it in a Rule, but not here.

Trouble Code

  <Step icon="Task" name="Set Identity Attribute">
    <Arg name="identityName" value="ref:identityName"/>
    <Script>
      <Source>
        	import sailpoint.tools.Util; 
        	import sailpoint.object.Identity;
        
        	Identity identity = context.getObjectByName(Identity.class, identityName);

          identity.setAttribute("iiqleaverdate", "");
          identity.setAttribute("termDate", "");
          identity.setAttribute("new_uname", "");
          identity.setAttribute("comments", "");

          context.saveObject(identity);
          context.commitTransaction(); 
          
      </Source>
    </Script>
    <Transition to="Refresh Identity"/>
  </Step>
  <Step action="call:refreshIdentity" condition="ref:doRefresh" icon="Task" name="Refresh Identity" posX="1028" posY="7">
    <Arg name="identityName" value="ref:identityName"/>
    <Arg name="refreshLinks" value="true"/>
    <Arg name="promoteAttributes" value="true"/>
    <Arg name="promoteManagedAttributes" value="true"/>
    <Arg name="refreshIdentityEntitlements" value="true"/>
    <Arg name="provision" value="true"/>
    <Arg name="refreshRoleMetadata" value="true"/>
    <Arg name="processTriggers" value="true"/>
    <Arg name="correlateEntitlements" value="true"/>
    <Arg name="synchronizeAttributes" value="true"/>
    <Transition to="Stop"/>
  </Step>
  <Step icon="Stop" name="Stop"/>
</Workflow>

What I am not sure about is why we are getting this type of Application error:
An unexpected error occurred: could not initialize proxy [sailpoint.object.Application#0ad200e18a191ba5818a19fbeb780018] - no Session

That application ID is the Active Directory application for us.

My hunch is that doing a commitTransaction and not doing something with the identity or context is what is messing us up. However, I am not sure where to start. Help is much appreciated.

Hi @acrumley
Alternatively, you can create an IIQ plan (see example, below) and use it for provisioning instead of directly setting the identity attribute. This approach is recommended as the best practice. To initiate provisioning, you can either invoke the out-of-the-box (OOTB) LCM Provisioning workflow or utilize a provisioner.

ProvisioningPlan plan = new ProvisioningPlan();
	Identity identity = context.getObjectByName(Identity.class, identityName);
	plan.setIdentity(identity);
	AccountRequest accountReq = new AccountRequest(AccountRequest.Operation.Modify,"IIQ",null,identityName);

	
	accountReq.add(new AttributeRequest("inactive", Operation.Set, true));
	plan.add(accountReq);

Do you recommend this approach even on a Joiner workflow process?

Also, for the call:refreshIdentity will that trigger the Provisioning Plans queued for that account?

Moderator Note Dec 2025
Please note that the response below is from AI and contains known errors. It is not being deleted as it was marked as a solution but proceed with caution and double check for accuracy.

@acrumley -

Why the LazyInitializationException shows up in this workflow

  1. context.commitTransaction() closes the Hibernate session for this step.
    When the step ends, the workflow engine expects the session that it opened at the beginning of the step to still be alive so it can flush and commit after the step finishes. Calling commitTransaction() yourself closes that session early and detaches every object that was loaded in it ( Identity, its Links, the Application proxies inside each link, etc.).
  2. call:refreshIdentity immediately runs in the very next step.
    refreshIdentity reloads the identity, then walks through the links (link.getApplication()), roles, entitlements, … If any of those objects are still the detached proxies that were created in the previous (now‑closed) session, Hibernate tries to initialise them and throws
org.hibernate.LazyInitializationException:
could not initialize proxy – no Session

This is exactly the pattern described in SailPoint’s developer thread on this error - org.hibernate.LazyInitializationException.
3. The proxy you see in the stack trace belongs to your AD application (Id 0ad200e18a19…), so the first lazy fetch that fails is link.getApplication().

The fix: let the workflow engine do the commit for you

<Step icon="Task" name="Set Identity Attribute">
    <Arg name="identityName" value="ref:identityName"/>
    <Script>
        <Source><![CDATA[
            import sailpoint.object.Identity;

            Identity identity =
                context.getObjectByName(Identity.class, identityName);

            // clear the attributes – use nulls if you really want them removed
            identity.setAttribute("iiqleaverdate", null);
            identity.setAttribute("termDate",        null);
            identity.setAttribute("new_uname",       null);
            identity.setAttribute("comments",        null);

            context.saveObject(identity);   // **no commitTransaction()**
            // If you want to be 100 % sure the row is written before
            // the next step starts you can add
            // sailpoint.tools.Util.flushContext(context);
        ]]></Source>
    </Script>
    <Transition to="Refresh Identity"/>
</Step>

Tip: If, for some reason, you absolutely must commit in the middle of the step, call

context.commitTransaction();
context.startTransaction();   // reopen a fresh session
and *do not* keep references to objects loaded in the old session. Reload them instead.

Best‑practice reminders

Topic Recommendation
Attribute clearing Use null (or identity.removeAttribute()) rather than empty string if you really want the attribute to disappear.
Locking When a workflow writes an Identity, use ObjectUtil.lockIdentity() if concurrent updates are possible.
Performance Excessive manual commitTransaction() calls can hurt overall throughput. Avoid them inside loops or high‑volume workflows.
Debugging If you still see lazy‑load errors, add log4j.logger.org.hibernate=debug to capture the exact field that fails, or reload the object in the current session (context.getObjectById(...)).

After removing the premature commit most teams find the refresh step runs without the “no Session” error. Let me know if you still see stack traces – we can look at log excerpts and tune the refresh arguments next.

Cheers!!!

This is an awesome reply! I will be sharing these best practices with my team. I believe your post contains the solution, but I do want to be sure that I am communicating properly. We are not getting the specific LazyInitializationException error. However, we are getting errors like this:


and

So I think your comment on the session being open or closed is the most pertinent. In our workflow, we actually use two different patterns,

For some, we use the access request and do a provisioning plan (because we want to see an M365 license get provisioned). However, we don’t want to see this backend identity attribute stuff show up in the Access Requests.

In places upstream in the workflow, we use a pattern like this:

      // Lock identity and set IIQJoinerDate to processing so another joiner is not ran
      ObjectUtil.lockIdentity(context, identity);
      identity.setAttribute("iiqjoinerdate", "PROCESSING");
      ObjectUtil.unlockIdentity(context, identity);

      // Save object and commit transaction
      context.saveObject(identity);
      context.commitTransaction();

And based on your best practices, it should be this:

      // Lock identity and set IIQJoinerDate to processing so another joiner is not ran
      ObjectUtil.lockIdentity(context, identity);
      identity.setAttribute("iiqjoinerdate", "PROCESSING");
      ObjectUtil.unlockIdentity(context, identity);
      context.saveObject(identity);
     ...
     // Let the refresh step do the committransaction()


This topic was automatically closed 60 days after the last reply. New replies are no longer allowed.