NullPointerException访问Singleton中的Neo4J数据库

时间:2013-05-28 14:00:05

标签: java nullpointerexception neo4j

我正在研究一个Neo4J数据库,在一个小社交网络中使用它。这个想法是: 作为用户,您连接到网站,它将您连接到N4J数据库。 我试图通过Singleton创建它来避免与db的多个实例相关的问题。但是,我认为我的用户必须能够“连接”和“断开连接”,所以我为此创建了方法,但是当我在用户上使用disconnect()时,其他人会因为他们可以''而运行NullPointerException。再也无法访问数据库(我认为这是由Singleton处理的)。

以下是代码,我相信这会使事情更加清晰:

我用来测试代码的主要内容:

public static void main(String[] args) {

        Node root;
        N4JAdmin admin = new N4JAdmin();

        Transaction tx = GraphDB.getGraphDb().beginTx();
        try {
            root = GraphDB.getGraphDb().createNode();
            root.setProperty("Nom", "aname");
            root.setProperty("Prenom", "afirstname");
            tx.success();
        } finally {
            tx.finish();
        }

        N4JUser sr = admin.addUser("Ribeiro", "Swen", 1);
        //14 more addUser, it creates nodes in the db with the 3 properties, works fine


//      The following connect() calls are commented because the errors occurs with or without them

//      sr.connect();
//      the 14 others...

        sr.addAcquaintance(cw.getUserNode());
        sr.addAcquaintance(fc.getUserNode());

        sr.disconnect();
        System.out.println("+++++++++ sr disconnected ++++++++++");

        bm.addAcquaintance(cm.getUserNode());
// and more operations...

        GraphDB.getGraphDb().shutdown();
    }

addAquaintance代码:

 public void addAcquaintance(Node target) {
            Transaction tx = GraphDB.getGraphDb().beginTx();
            try {           
                this.userNode.createRelationshipTo(target, RelTypes.CONNAIT);
                System.out.println(this.userNode.getProperty("Nom")+" "+this.userNode.getProperty("Prenom")+" est maintenant ami avec : "+ target.getProperty("Nom")+" "+target.getProperty("Prenom"));
                tx.success();
            } finally {
                tx.finish();
            }
        }

GraphDB类,这是我的Singleton:

public final class GraphDB {

    private static final String DB_PATH = "/Workties/database/workties.db";
    private static GraphDatabaseService graphDb;
    private static boolean instanciated = false;

    private GraphDB(){
        GraphDB.graphDb = new GraphDatabaseFactory().newEmbeddedDatabase(DB_PATH);
        registerShutdownHook(graphDb);
        GraphDB.instanciated = true;
    }

    private static void registerShutdownHook( final GraphDatabaseService graphDb ){
        Runtime.getRuntime().addShutdownHook( new Thread(){
            @Override
            public void run(){
                graphDb.shutdown();
            }
        } );
    }

    public static GraphDatabaseService getGraphDb(){
        if (!GraphDB.instanciated) {
            new GraphDB();
            System.out.println("New connection : " +GraphDB.graphDb.toString());
        }
        return GraphDB.graphDb; 
    }
}

注意:稍后添加了instanciated属性,但即使没有它也不起作用。

我的问题来自于我认为使用Singleton不会发生这种类型的错误,所以我有点卡住......

提前感谢您的帮助!

编辑:断开连接方法:

public void disconnect(){
        GraphDB.getGraphDb().shutdown();
    }

1 个答案:

答案 0 :(得分:3)

您不应该为每个用户调用shutdown - 一旦首次实例化数据库,就足以让您完成所有查询等等。为什么要连接和断开连接?

nullpointer是因为shutdown关闭了Neo4j,但你的单例仍然认为instanciated = true,所以它返回一个实际上并不存在的graphDb的句柄。即使没有你添加的instanciated变量,单例也会在关闭后保持对graphDb的引用。 除非您的应用程序正在终止,否则强烈建议不要进行关机。