Bryan Schmiedeler
Bryan Schmiedeler

Reputation: 3137

Xpages: How to access database from CacheBean

I have a cacheBean called PCConfig in which I want to store references to databases, so I can access them in other Java methods.

Here is the relevant part of my cacheBean:

package com.scoular.cache;

import java.io.Serializable;
import java.util.HashMap;
import java.util.Vector;
import org.openntf.domino.utils.Factory;
import org.openntf.domino.xsp.XspOpenLogUtil;
import org.openntf.domino.Database;
import org.openntf.domino.Session;
import org.openntf.domino.View;
import org.openntf.domino.ViewEntry;
import org.openntf.domino.ViewNavigator;

public class PCConfig implements Serializable {

    private static final long serialVersionUID = 1L;

    private static Database PCDataDB;

    // @SuppressWarnings("unchecked")
    private void initConfigData() {
        try {
            loadStatus();
            loadGeoLocations();
            loadModels();
            loadDatabases();
        } catch (Exception e) {
            XspOpenLogUtil.logError(e);
        }
    }

    public PCConfig() {
        initConfigData();
    }

    //Getters   

    public static Database getPCDataDB() {
        return PCDataDB;
    }

    public static void setPCDataDB(Database dataDB) {
        PCDataDB = dataDB;
    }

    public static void loadDatabases() {
        loadPCDataDB();     
    }

    public static void loadPCDataDB() {
        Session session = Factory.getSession();
        PCConfig.PCDataDB = session.getDatabase(thisDB.getServer(),"scoApps\\PC\\PCData.nsf", false);
    }


    }
}

In a different java class I import the PCConfig class and try to use this method getPCDataDB(). I have also tried PCConfig.PCDataDB.

I always get the error null pointer exception.

What am I doing wrong?

public void loadByUnid(String unid) {
    try {
        Document doc = PCConfig.getPCDataDB().getDocumentByUNID(unid);
        if (null == doc) {
            System.out.println("Document not found");
        } else {
            loadValues(doc);
        }
    } catch (Exception e) {
        XspOpenLogUtil.logError(e);
    }
}

Upvotes: 1

Views: 106

Answers (2)

Paul Stephen Withers
Paul Stephen Withers

Reputation: 15739

As Knut says, storing the database in your static class won't work. Normally you would need to store the server and the database path as separate variables. But since you're using the OpenNTF Domino API, you can take advantage of Database.getApiPath() , which returns a "metaReplicaID" - a combination of servername and replica ID. You can store that and you have a direct reference to where the database resides. You can then use session.getDatabase(metaReplicaID) to retrieve the database when required.

Upvotes: 1

Knut Herrmann
Knut Herrmann

Reputation: 30970

You call the static method getPCDataDB(). As it is static you don't need to instantiate the class. But, your private field Database PCDataDB is not initialized at this point. This only happens if you instantiate the class. That's why you get the null pointer exception.

I guess PCConfig is a managed bean. It would get instantiated automatically if you call a non-static method in SSJS. So, remove all static in your class and it should work. If you want to use the class in Java then instantiate the class before calling getPCDataDB():

    PCConfig pcConfig = new PCConfig();
    Document doc = pcConfig.getPCDataDB().getDocumentByUNID(unid);

It is not recommended to keep Domino objects as class fields (like your Database PCDataDB) as they are not serializable. They might get recycled over the time especially if the class object resides in a long life scope like application scope. It is better to keep the data itself in fields or in your case database's server name and path so that you can open the database again when you need it.

BTW private Database PCDataDB should be private Database pCDataDB. The convention is that only class names and interfaces start with a capital letter.

Upvotes: 2

Related Questions