Monday, March 5, 2012

Using the ADF BC userData object

Introduction

ADF BC provides a userData object that is stored in the session.  It is useful for storing data related to the user and/or the session.  However, there are some nuances you need to address.

The following applies to ADF 11.1.1.3.

The userData object

The userData object is a Hashtable.  Key/value pairs are stored as type Object.  Here's an example of storing data.  Note that the "userId" in this example is originally of type oracle.jbo.domain.Number.

    protected void storeUserDetails(Number userId, String userName) {
        this.getSession().getUserData().put("userId", userId);
        this.getSession().getUserData().put("userName", userName);
    }


You can then retrieve the values like this:

    Number userId =
        (Number)this.getSession().getUserData().get("userId");
    String userName = this.getSession().getUserData().get("userName");


Problem

However, when the Application Module passivates, the userData is lost.  To keep the userData, you must include custom code in your Application Module class.  This post has good example code for this.  Note however that the example code stores and retrieves the values as String in an XML "TextNode".  This causes a problem when you try to retrieve a Number after a passivation/activation cycle.  Executing this ...

    Number userId = this.getSession().getUserData().get("userId");

  ... will now cause "java.lang.ClassCastException: java.lang.String cannot be cast to oracle.jbo.domain.Number"

Solution

Use a helper method to retrieve Numbers from the userData object.

Here' s the helper method:

    public Number getNumber(Object obj) {
        Number num = null;
        try {
            num = new Number(obj);    // Works when value is a String
        } catch (SQLException sqle) {
            num = (Number)obj;    // Works when value is an Object
        }
        return num;
    }


Here's it's usage within a VO implementation class:

    MyAppModuleImpl am = (MyAppModuleImpl)this.getApplicationModule();
    Number userId =

        am.getNumber(am.getSession().getUserData().get("userId"));

This helper method works whether the userData object has been passivated/activated or not.

1 comment:

  1. Thank you for this post; it was a good explanation of the problem and you provided an elegant solution.

    ReplyDelete