1
votes

I created a Managed Bean that reads a sequence of documents from a view and creates a HashMap entry for each of the documents. Each Hash Map entry contains a series of values retrieved from the document, These values seldom change and are used in many places. In any case the building of the HashMap works and stores the correct values. If I create the constructor as follows:

private final Map<String, AppProperties> internalMap = new HashMap<String, AppProperties>();

    public ApplicationMap() {
        System.out.println("In Constructor");
        if (this.internalMap.isEmpty()){
            System.out.println("Is Empty ");
            this.buildMap(this.internalMap);
        }
    }

The constructor always sees the internalMap as being empty and rebuilds it. I have tried to do the same thing in the Get method (making the contructor public ApplicationMap() {} )

Checking to see if it has a value:

public AppProperties get(Object key) {
        System.out.println("in Get");
            try {
            if (this.internalMap.containsKey(key)) {
                System.out.println("Has Key" + key);
                return this.internalMap.get(key);

            } else {
                this.buildMap(this.internalMap);
                if (this.internalMap.containsKey(key)) {
                    System.out.println("Has Key" + key);
                    return this.internalMap.get(key);

                } else {
                    System.out.println("No Key in ApplicationMap " + key);
                    AppProperties ap = new AppProperties();
                    return ap;
                }
            }
        } catch (Exception e) {
            System.out.println("ApplicationMap" + e.toString());
            AppProperties ap = new AppProperties();
            return ap;
        }

    }

but this seems to never find the key value and goes through the this.buildMap every time. So I'm obviously missing something. I think that putting the buildMap in the get would appear to be the right place to do this but

Here is an abbreviated code of the buildMap:

private void buildMap(Map<String, AppProperties> theMap) {

        try {
            Session s = ExtLibUtil.getCurrentSession();
            mainDB = s.getCurrentDatabase();
            vwApps = mainDB.getView("vwWFSApplicationsEnabled");
            serverName = s.createName(mainDB.getServer()).getCommon();
            veCol = vwApps.getAllEntries();
            ve = veCol.getFirstEntry();
            tVE = null;
            while (ve != null) {
                AppProperties ap = new AppProperties();
                tVE = veCol.getNextEntry(ve);
                colVal = ve.getColumnValues();
                appName = colVal.get(0).toString();
                System.out.println("Application = " + appName);
                String tAppRepID = colVal.get(3).toString();
                ap.setAppRepID(colVal.get(3).toString());
                ap.setHelpRepID(colVal.get(4).toString());
                ap.setRuleRepID(colVal.get(5).toString());
                System.out.println("Put Map");
                theMap.put(appName, ap);
                //System.out.println("Recycle ve");
                ve.recycle();
                ve = tVE;
            }
            //System.out.println("Finished Loop");
        } catch (Exception e) {
            System.out.println(e.toString());
        } finally {
            Utils.recycleObjects( vwApps, vwForms, ve, veCol,);
            //System.out.println("Finally Finished");
        }
    }
2
Did you try removing final keyword from the internalMap.Serdar Basegmez
Took the final out but it still says that the internalMap is always empty and reloads it.Bill F
The problem was entirely involved with how I called the bean from SSJS was calling it WFSAppProperties().get(some Key).getAppFilePath() while it should be WFSAppProperties.get(some key).getAppFilePath(). Many of my calls to the bean were from EL and they all work as expected so I didn't see the error until I was tracing a bug in some SSJS that called the bean and noticed it always considered the internalMap Empty. Unrelated to the SSJS bug I was trying to fix. So I then had two bugs and looked and looked at the bean code and fiddled with it, when the problem was in how it was called.Bill F
You know what, I have noticed that problem in one of your previous questions. I have not thought such a problem though. :)Serdar Basegmez

2 Answers

1
votes

The constructor gets called only ones for an object, always. That's why internalMap is always empty in constructor.

Don't give your private method buildMap a parameter and access internalMap there direct instead.

1
votes

I have a software development axiom - Bugs that are easy to find are hard to fix, while bugs that are hard to find are easy to fix, and this one is a classic case. The solution is that when I call the bean from SSJS I used the sysntax: WFSAppProperties().get(Some Key Value).getAppFilePath(); When doing this the internalMap was always considered empty, however, it needs to be: WFSAppProperties.get(Some Key Value).getAppFilePath(); Both cases return the correct value but the first one always reloads the internalMap while the second only loads the internalMap once on initial load as it should be. When called by EL it has always worked correctly. Thanks to Knut for his time and patience with a struggling JAVA Bean newby.