我正在研究一个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();
}
答案 0 :(得分:3)
您不应该为每个用户调用shutdown - 一旦首次实例化数据库,就足以让您完成所有查询等等。为什么要连接和断开连接?
nullpointer是因为shutdown关闭了Neo4j,但你的单例仍然认为instanciated = true,所以它返回一个实际上并不存在的graphDb的句柄。即使没有你添加的instanciated变量,单例也会在关闭后保持对graphDb的引用。 除非您的应用程序正在终止,否则强烈建议不要进行关机。