May 30, 2012

Retrieve multiple attribute values from an Mbo

This entry is part of the Maximo Java Development series.

Maximo MBOs are not exactly lightweight, however there are some little tricks to improve performances and reduce system resources consumption.
One of the most common mistakes that I have seen is the redundant use of getters methods of the psdi.mbo.Mbo class.
In the following example three calls to getString/getInt methods are made to retrieve the attribute values from an Mbo object.

MboSetRemote mboset = getMboSet("ASSET");
MboRemote asset = mboset.getMbo(0);

String assetnum = asset.getString("ASSETNUM");
String assetdesc = asset.getString("DESCRIPTION");
int assetPriority = asset.getInt("PRIORITY");
Rather than retrieving data from attributes individually you can use the getMboValueData(String[]) method to retrieve several attributes in a single call.
String[] attrs = { "ASSETNUM", "DESCRIPTION", "PRIORITY" };

MboSetRemote mboset = getMboSet("ASSET");
MboRemote asset = mboset.getMbo(0);

MboValueData[] valData = asset.getMboValueData(attrs);
String assetnum = valData[0].getData();
String assetdesc = valData[1].getData();
int assetPriority = valData[2].getDataAsInt();

This implementation is more efficient because it makes only one remote call to the server instead of three.

Going one step further, it is possible to apply the same approach on the MboSet. In the following snippet the three attributes are retrieved in one call for the first 10 rows of the MboSet.
String[] attrs = { "ASSETNUM", "DESCRIPTION", "PRIORITY" };
MboSetRemote mboset = getMboSet("ASSET");

MboValueData[][] valData = mboset.getMboValueData(0, 10, attrs);
String assetnum0 = valData[0][0].getData();
String assetdesc0 = valData[0][1].getData();
int assetPriority0 = valData[0][2].getDataAsInt();
String assetnum1 = valData[1][0].getData();
...
The first parameter of getMboValueData method is the starting position of the required Mbo in the MboSet. The second parameter is the number of Mbos required. Passing MboConstants.ALLROWS the entire MboSet is retrieved.

7 comments:

  1. I need to connect to remote db using Interface table ENDPOINT details like driver, username, url and password from a custom cron task.
    I am retrieving the values from MAXENDPOINTDTL table using getMboSet("MAXENDPOINTDTL"), I am not able to get value for Password as it is encrypted.
    Is there any way to get the actual password value in the code.

    ReplyDelete
    Replies
    1. I'm not sure but I would try playing with psdi.util.MXCipherX class.
      Try something like this.

      MXCipher cipher = MXServer.getMXServer().getMXCipher();
      byte[] crypPass = mbo.getBytes("password");
      String password = cipher.decData(crypPass);

      Please let me know if it works.

      Delete
    2. Hi Bruno,

      The above code is not working as expected, If we try to decrypt password '10fe6f4650b2acb49a2121d7e6133e64', it is not decrypting to maxadmin and throwing error.

      javax.crypto.BadPaddingException: Given final block not properly padded

      [9/8/15 14:21:13:571 EDT] 00000043 SystemErr R at com.ibm.crypto.provider.DESedeCipher.engineDoFinal(Unknown Source)

      [9/8/15 14:21:13:571 EDT] 00000043 SystemErr R at com.ibm.crypto.provider.DESedeCipher.engineDoFinal(Unknown Source)

      [9/8/15 14:21:13:571 EDT] 00000043 SystemErr R at javax.crypto.Cipher.doFinal(Unknown Source)

      [9/8/15 14:21:13:571 EDT] 00000043 SystemErr R at psdi.util.MXCipher.decData(MXCipher.java:263)

      Delete
  2. Hi Bruno,

    Is there any method to retrieve all of the attribute values from a MboRemote? Or get any attribute values without any specified attribute names?

    Thanks!

    ReplyDelete
  3. Hi Bruno,

    I am new to maximo development. I am trying to test your script as I have to perform math functions of over 100 numvalues. Instead of our conventional way of using a getvalue, I stumbled upon this article and would like to hit the DB once.

    I am trying it as a Jython automation script, but it appears to be complaining about the [] where we are defining the arrays. Both spots on the code String [] attrs and MboValueData[] valdata.

    Any hints?

    ReplyDelete
  4. Hello Bruno,

    You said:
    > This implementation is more efficient because it makes only one remote call to the server instead of three.

    As I understood it, the MBO will have all persistent values on hand for a given MBO, since the MBO is ultimately fetched as a "SELECT * FROM foo" statement. That would suggest that the "remote call" you are referring to is not DB traffic.

    Am I correct in inferring, then, that this optimization is predicated upon the use and overhead of RMI? If so, in what contexts/components have you seen this kind of issue, where RMI is the presumed default?

    Thank you.

    ReplyDelete
    Replies
    1. You are totally right.
      There is no additional database transaction, just more RMI calls.

      Delete