I am developing custom rule, where I am filtering application accounts using QueryOptions.
I am getting Identity from Link. I am able to get only first Identity.
When Its reached to get the second identity I am getting LazyInitializationException.
The same code is working fine when I use hardcoded value in IdentityName in Filter.
org.hibernate.LazyInitializationException: could not initialize proxy [sailpoint.object.Identity#(Identity id will show here)] - no Session
Below is the code:
Filter filter=Filter.join("identity","Identity.id");
filter=Filter.and(filter,Filter.join("application","Application.id"));
filter=Filter.and(filter,Filter.eq("application.name","ADApplicationName"));
filter=Filter.and(filter,Filter.eq("identity.identityState","active"));
QueryOptions qo=new QueryOptions();
qo.addFilter(filter);
List acctList=context.getObjects(Link.class,qo);
for(Link link : acctList)
{
Identity id_obj=link.getIdentity();
}
when I give identityName as hardcoded value as below in filter its not throwing any exception. Rule is running fine.
Hello @ArunSundar_vas, Firstly warm welcome to the SailPoint Developer Community!
Secondly, it seems that the initialisation issue might be here Identity id_obj=link.getIdentity(); can you try to use search instead of getObjects, you will get an iterator. Parse through it and get a fresh link obj everytime.
Iterator itr=context.search(Link.class,qo);
while(itr.hasNext())
{
Link l = itr.next();
Identity id = link.getIdentity();
}
There is an easy fix that will require much more data to be loaded at query time: qo.setCloneResults(true).
This will tell Hibernate to make copies of all of the objects returned from context.getObjects(), rather than using “live” objects that require a continued session. All of the nested references, including your Identity, will be loaded and detached from the session before getObjects returns.
There is a downside: If the same Link object is loaded by Hibernate elsewhere in the same appserver at the same time, your clone may be outdated when you go to saveObject. You will get an error if that’s the case.
The other, probably safer option is sailpoint.api.IncrementalObjectIterator.
This runs your query, but only grabs the id from each object. Then, each time you call iterator.next() on it, it reads the object by ID right before returning it to you. Unlike context.search, this does not require that you hold a query session open, so will be safer.
Iterator<Link> iterator = new IncrementalObjectIterator(context, Link.class, qo)