There are two ways of fetching a MboSet in java code, either using a relationship or through MXserver. There are different benefits for using either of these and different scenarios may need one of these ways to be used. For now, we are going to talk about MboSet fetched from MXServer.
When fetching a MboSet from MXServer, there are a few things that one needs to be careful about. Poor knowledge of these may result in performance issues, poor memory management and undesirable outcomes.
There are six simple rules to keep in mind when fetching MboSet from MXserver. These rules are as follows –
- Always use setWhere() and reset() on the set fetched from MXServer. The where clause that you give in the setWhere will reduce the no. of MBOs fetched in the set. The reset will get the data from the database using the where clause. If the setWhere is not used, the entire set is fetched from the database which means the entire table is fetched into the memory.
MboSetRemote assetSet = MXServer.getMXServer().getMboSet("ASSET", getUserInfo()); assetSet.setWhere("LOCATION = 'BEDFORD'"); assetSet.reset();
- If the set is being fetched just to add new MBOs and not for traversing then use 1=0 as where clause in the setWhere. This will fetch an empty set.
assetSet.setWhere("1=0"); assetSet.reset();
- If the set is being fetched just for traversing and not for any addition or updates set DISCARDABLE flag as true on the MboSet. Discardable MboSets are not cached in memory, they can only be traversed in forward direction and cannot be saved.
assetSet.setFlag(DISCARDABLE, true);
- If MboSet is fetched for readonly purpose, set NOSAVE flag as true. This way the MboSet won’t be added to the MXTransaction which would shortens the looping time of the transaction.
assetSet.setFlag(NOSAVE, true);
- If an add or update transaction is being performed on an MboSet, do not forget to call save(). Contrary to popular belief that save shouldn’t be called explicitly in java code, MboSet fetched from MXServer must be saved before the set is closed otherwise the changes would be lost. MboSets fetched from relationship do not require a save to be called explicitly because their save is called when their parent is saved. Hence the belief.
- Always call clear() and close() on the MboSet fetched from MXServer once it is certain that it is not required anymore. This releases the memory and the database resources. If the set is not closed, it will remain in memory till it is collected by the garbage collector which could be a long time.
assetSet.clear(); assetSet.close();
clear and close shouldn’t be called on an MBOSet fetched from a relationship. This will give undesirable results.
So keep in mind these simple rules next time when you are fetching a set from MXServer.
In my next post I will try to explain you the difference between clear(), cleanup() & close(). Stay tuned.. 🙂
Can you point me to this discussion?
In my next post I will try to explain you the difference between clear(), cleanup() & close(). Stay tuned
Hey Tom! I am yet to write that post. As soon as write it i’ll sent you the link.
Thanks.
Hello,
For the point “2”:
{
If the set is being fetched just to add new MBOs and not for traversing then use 1=0 as where clause in the setWhere. This will fetch an empty set.
}
I prefer using a dynamic relationship :
MboRemoteSet assetSet = getMboSet(“$RELATIONShipname”; “ASSET”; “1=2”);
MboRemote newAsset = assetSet.add();
==> This way, no save(), no close()… needed.
Sorry I missed this.
Correction you need to do –
MboRemoteSet assetSet = parentMbo.getMboSet(“$RELATIONShipname”; “ASSET”; “1=2”);
and yes if you do this, you don’t have to call save explicitly. When the parent would be saves this will also get saved.
In Integration User Exist Automation scripts(java Script), how do we get logging ? print doesn’t work and even service.log is not.
Define a logger in the automation script and use it to write to the SystemOut.log.
from psdi.util.logging import MXLoggerFactory
logger = MXLoggerFactory.getLogger(“maximo.autoscript.xyzscript”)
logger.info(“>>>code execution started<<<“)
logger.debug(“WONUM: ” + mbo.getString(“WONUM”))
Make sure that you set up the logger (maximo.autoscript.xyzscript in this example) in the logging application and set the appropriate logging level on it.
Thank You for the updates.
That is what I am trying to avoid.
I was trying to find if there is any reason why print and service.log doesn’t work. Because Automation scripting framework by default support it. So is there anything special we have do when we write script on USER exist ?
If nothing works out then I have to go for what you mentioned. But I was trying to maintain uniformity across all my scripts.
assetSet.clear(); and assetSet.close(); only for persistent mbo
for non-persistent only assetSet.clear();
is it right?
That is correct.
There is no need to do assetSet.reset(); if you do assetSet.setWhere(“some condition”); first time.
Only do assetSet.reset(); if you update setWhere condition and want to refetch the data.
That is correct, the moveFirst() or getMbo(i) will do the job of fetching the set for the first time. reset() is required to re-fetch the set if it’s whereclause is changed.
Nice one, Pranjal!
good posts