尝试使用 OrientDB [英] Trying to work with OrientDB

查看:66
本文介绍了尝试使用 OrientDB的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试这个简单的代码:

I am trying this simple code:

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

它输出到控制台:

TestObject{prop1: 'captivation', prop2: 'Caribbean's', prop3: -1912492199, prop4: 0.9350339155517686, prop5: false}
TestObject{prop1: 'null', prop2: 'null', prop3: 0, prop4: 0.0, prop5: false}

而我预计第一行会输出两次.任何人都可以发现它有什么问题吗?

Whereas I have expected the first line to be output twice. Can anyone spot what's the problem with it?

EDIT1

这是 TestObject.java:

Here is 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 以包含以下字段:

Changed TestObject.java to include the following field:

  @javax.persistence.Id
  private Object id;

并添加到toString().现在程序打印:

And added to toString(). Now the program prints:

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 方法.我不知道为什么不调用处理程序.

The problem is that OObjectProxyMethodHandler.invoke() is not called, even though db.newInstance does return a proxy and I set the properties using TestObject.setXXX methods. I have no idea why the handler is not called.

EDIT4

好的,处理程序的问题在于 OObjectMethodFilter 实现的方法过滤器正在检查方法是否由使用特定命名方案命名的字段支持.TestObject 类不遵循该方案 - 它使用 m_ 前缀作为私有字段,这会导致过滤器测试失败.删除了前缀,现在 OObjectProxyMethodHandler.invoke() 被调用.然而,最终的结果还是一样.进一步调查.

OK, the problem with the handler was that the method filter implemented by OObjectMethodFilter was checking that methods are backed by fields named using a certain naming scheme. The TestObject class does not follow that scheme - it uses the m_ prefix for the private fields, which fails the filter test. Removed the prefix, now OObjectProxyMethodHandler.invoke() is called. However, the final result is still the same. Investigating further.

推荐答案

这没有按预期工作的最可能原因是您没有使用 TestObject setter/getter 方法来设置/检索字段值.OrientDB Java 代理对象拦截" set/get 调用以在后台执行必要的管理;特别是,setter 将字段标记为脏(对于 db.save()),getter 将从数据库中获取延迟加载的字段数据(在加载之前,字段将具有默认值).正如您所指出的,setter/getter 应该遵循与字段名称相关的 Java 命名约定.

The most likely reason that this isn't working as you expected is that you're not using the TestObject setter/getter methods to set/retrieve the field values. The OrientDB Java proxy objects "intercept" the set/get calls to perform necessary management behind-the-scenes; in particular, the setters will mark fields as dirty (for db.save()) and the getters will fetch lazy-loaded field data from the db (fields will have default values until loaded). As you noted, it's expected that the setters/getters follow Java naming conventions with respect to the field names.

在您的示例程序中,您在 filler.randomFill(db.newInstance(TestObject.class)) 中填充示例 TestObject 后,它被 DB 代理>.因此,您的 randomFill 在填充 TestObject 的字段时必须使用 setter.

In your example program, you're populating the sample TestObject after it's been proxied by the DB, in filler.randomFill(db.newInstance(TestObject.class)). As a result, your randomFill must use setters when populating the TestObject's fields.

同样,您的 TestObject.toString() 输出显示空/默认值,因为您(最有可能)直接访问字段而不是使用 getter.代理是延迟加载字段数据,因此在调用相应的get方法触发加载之前不会填充该字段.

Similarly, your TestObject.toString() output is showing null/default values because you're (most likely) directly accessing the fields instead of using the getters. The proxy is lazy-loading field data, so the field won't be populated until the load is triggered by calling the corresponding get method.

当我修改您的测试代码以在 TestObject 上使用 setter/getter 方法时,我得到了两次相同的行输出,正如预期的那样.

When I modify your test code to use setter/getter methods on TestObject, I get the same line output twice, as expected.

另见:OrientDB Object2RecordJavaBinding

这篇关于尝试使用 OrientDB的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆