Java 尝试使用OrientDB
我正在尝试以下简单代码:Java 尝试使用OrientDB,java,orientdb,Java,Orientdb,我正在尝试以下简单代码: import java.util.List; import com.orientechnologies.orient.core.exception.OStorageException; import com.orientechnologies.orient.core.sql.query.OSQLSynchQuery; import com.orientechnologies.orient.object.db.OObjectDatabasePool; import co
import java.util.List;
import com.orientechnologies.orient.core.exception.OStorageException;
import com.orientechnologies.orient.core.sql.query.OSQLSynchQuery;
import com.orientechnologies.orient.object.db.OObjectDatabasePool;
import com.orientechnologies.orient.object.db.OObjectDatabaseTx;
public class ProgramOrientDB {
private static TestObjectFiller filler = new TestObjectFiller();
private static interface DBCallback<T> {
T call(OObjectDatabaseTx db) throws Exception;
}
private static <T> T execWithDB(DBCallback<T> cb) throws Exception {
OObjectDatabaseTx db;
try {
db = OObjectDatabasePool.global().acquire("local:c:/tmp/odb", "admin", "admin");
} catch (OStorageException exc) {
db = new OObjectDatabaseTx("local:c:/tmp/odb");
db.create();
}
try {
return cb.call(db);
} finally {
db.close();
}
}
private static TestObject dump(TestObject o) {
System.out.println(o);
return o;
}
public static void main(String[] args) throws Exception {
Runtime run = Runtime.getRuntime();
Process pr = run.exec("cmd /c del /s/q c:\\tmp\\odb");
pr.waitFor();
execWithDB(new DBCallback<Void>() {
@Override
public Void call(OObjectDatabaseTx db) throws Exception {
db.getEntityManager().registerEntityClass(TestObject.class);
dump((TestObject)db.save(filler.randomFill(db.newInstance(TestObject.class))));
return null;
}
});
execWithDB(new DBCallback<Void>() {
@Override
public Void call(OObjectDatabaseTx db) throws Exception {
db.getEntityManager().registerEntityClass(TestObject.class);
for (TestObject o : (List<TestObject>)db.query(new OSQLSynchQuery<TestObject>("select * from TestObject"))) {
System.out.println(o);
}
return null;
}
});
}
}
然而,我期望第一行输出两次。有人能发现它有什么问题吗
EDIT1
下面是TestObject.java:
public class TestObject {
private String m_prop1;
private String m_prop2;
private int m_prop3;
private double m_prop4;
private boolean m_prop5;
public String getProp1() {
return m_prop1;
}
public void setProp1(String prop1) {
m_prop1 = prop1;
}
public String getProp2() {
return m_prop2;
}
public void setProp2(String prop2) {
m_prop2 = prop2;
}
public int getProp3() {
return m_prop3;
}
public void setProp3(int prop3) {
m_prop3 = prop3;
}
public double getProp4() {
return m_prop4;
}
public void setProp4(double prop4) {
m_prop4 = prop4;
}
public boolean isProp5() {
return m_prop5;
}
public void setProp5(boolean prop5) {
m_prop5 = prop5;
}
@Override
public String toString() {
final StringBuilder sb = new StringBuilder();
sb.append("TestObject");
sb.append("{prop1: '").append(m_prop1).append('\'');
sb.append(", prop2: '").append(m_prop2).append('\'');
sb.append(", prop3: ").append(m_prop3);
sb.append(", prop4: ").append(m_prop4);
sb.append(", prop5: ").append(m_prop5);
sb.append('}');
return sb.toString();
}
}
EDIT2
将TestObject.java更改为包含以下字段:
@javax.persistence.Id
private Object id;
并添加到toString()。现在程序打印:
TestObject{id: 'null', prop1: 'gnaw', prop2: 'fishermen', prop3: -322577834, prop4: 0.7442149523357203, prop5: true}
TestObject{id: 'null', prop1: 'null', prop2: 'null', prop3: 0, prop4: 0.0, prop5: false}
这没什么好的
EDIT3
问题是没有调用OObjectProxyMethodHandler.invoke()
,即使db.newInstance
返回代理,我使用TestObject.setXXX
方法设置属性。我不知道为什么没有调用处理程序
EDIT4
好的,处理程序的问题是由
OObjectMethodFilter
实现的方法过滤器正在检查方法是否由使用特定命名方案命名的字段支持。TestObject
类不遵循该方案-它对私有字段使用了m
前缀,这导致筛选测试失败。删除了前缀,现在调用了OObjectProxyMethodHandler.invoke()
。然而,最终的结果仍然是一样的。进一步调查 似乎很奇怪,输出没有记录的RID。您是否出于布局目的删除了它们?这没有按预期工作的最可能原因是您没有使用TestObject setter/getter方法来设置/检索字段值。OrientDB Java代理对象“拦截”set/get调用,以便在后台执行必要的管理;特别是,setter将字段标记为dirty(对于db.save()
),getter将从db中获取延迟加载的字段数据(在加载之前,字段将具有默认值)。正如您所指出的,对于字段名,setter/getter应该遵循Java命名约定
在您的示例程序中,您将在DB代理示例TestObject之后,在filler.randomFill(DB.newInstance(TestObject.class))
中填充它。因此,在填充TestObject的字段时,randomFill必须使用setter
类似地,TestObject.toString()输出显示空/默认值,因为您(很可能)直接访问字段,而不是使用getter。代理是延迟加载字段数据的,因此在通过调用相应的get方法触发加载之前,不会填充字段
当我修改您的测试代码以在TestObject上使用setter/getter方法时,正如预期的那样,我得到了两次相同的行输出
另请参见:找不到关于如何开始的详细指南,因此出现了愚蠢的错误。我不清楚怎么做,只是从阅读添加了Id字段,仍然没有骰子。添加getter/setter也为Id。真的吗?我会试试,但是?明确地说:“不要为它创建GETTER/SETTER,以防止用户应用程序进行更改。”我刚刚尝试过它——不起作用。在
db.save
之后,id保持为空。是的,该行为是由延迟加载字段数据引起的。在使用正确的getter方法之前(也在代理对象的其他方法中),对象字段为null
。这应该是公认的答案。
TestObject{id: 'null', prop1: 'gnaw', prop2: 'fishermen', prop3: -322577834, prop4: 0.7442149523357203, prop5: true}
TestObject{id: 'null', prop1: 'null', prop2: 'null', prop3: 0, prop4: 0.0, prop5: false}