Xpages:如何从CacheBean访问数据库

时间:2016-04-29 00:05:02

标签: xpages javabeans

我有一个名为PCConfig的cacheBean,我想在其中存储对数据库的引用,因此我可以在其他Java方法中访问它们。

这是我的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);
    }


    }
}

在另一个java类中,我导入了PCConfig类并尝试使用此方法getPCDataDB()。我也尝试过PCConfig.PCDataDB。

我总是得到错误空指针异常。

我做错了什么?

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);
    }
}

2 个答案:

答案 0 :(得分:2)

您调用静态方法getPCDataDB()。由于它是静态的,因此您不需要实例化该类。但是,您的私有字段Database PCDataDB此时尚未初始化。只有在实例化类时才会发生这种情况。这就是你得到空指针异常的原因。

我猜PCConfig是托管bean。如果在SSJS中调用非静态方法,它将自动实例化。所以,删除您班级中的所有static,它应该有效。如果要在Java中使用该类,则在调用getPCDataDB()之前实例化该类:

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

不建议将Domino对象保留为类字段(如Database PCDataDB),因为它们不可序列化。它们可能会在一段时间内被回收,特别是如果类对象存在于应用程序范围等长寿命范围内。最好将数据本身保存在字段或案例数据库的服务器名称和路径中,以便您可以在需要时再次打开数据库。

BTW private Database PCDataDB应为private Database pCDataDB。惯例是只有类名和接口以大写字母开头。

答案 1 :(得分:1)

正如Knut所说,将数据库存储在静态类中不会起作用。通常,您需要将服务器和数据库路径存储为单独的变量。但是,既然您正在使用OpenNTF Domino API,那么您可以利用Database.getApiPath(),它返回一个" metaReplicaID" - 服务器名称和副本ID的组合。您可以存储它,并且您可以直接引用数据库所在的位置。然后,您可以在需要时使用session.getDatabase(metaReplicaID)检索数据库。