1

私はこの簡単なコードを試しています:

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}

最初の行が2回出力されると予想していましたが。何が問題なのか誰にもわかりますか?

編集1

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.newInstanceTestObject.setXXX

EDIT4

OK、ハンドラーの問題は、によって実装されたメソッドフィルターがOObjectMethodFilter、特定の命名スキームを使用して名前が付けられたフィールドによってメソッドがサポートされていることを確認していたことです。TestObjectクラスはそのスキームに従っていません。プライベート フィールドにプレフィックスを使用しているためm_、フィルター テストに失敗します。接頭辞を削除し、現在OObjectProxyMethodHandler.invoke()は と呼ばれています。ただし、最終的な結果は同じです。さらに調査中。

4

2 に答える 2

1

出力にレコードの RID がないのはかなり奇妙に思えます。レイアウトのためにそれらを削除しましたか?

于 2013-03-19T16:01:57.917 に答える
1

これが期待どおりに機能しない理由として最も可能性が高いのは、TestObject セッター/ゲッター メソッドを使用してフィールド値を設定/取得していないことです。OrientDB Java プロキシ オブジェクトは、set/get 呼び出しを「インターセプト」して、必要な管理をバックグラウンドで実行します。特に、セッターはフィールドをダーティ (for db.save()) としてマークし、ゲッターは遅延ロードされたフィールド データを db からフェッチします (フィールドはロードされるまでデフォルト値を持ちます)。ご指摘のとおり、セッター/ゲッターはフィールド名に関して Java 命名規則に従うことが期待されます。

サンプル プログラムでは、サンプル TestObjectが DB によってプロキシされたfiller.randomFill(db.newInstance(TestObject.class))、 . そのため、RandomFill は、TestObject のフィールドにデータを入力するときにセッターを使用する必要があります。

同様に、(ほとんどの場合) ゲッターを使用する代わりにフィールドに直接アクセスしているため、 TestObject.toString() 出力に null/default 値が表示されます。プロキシはフィールド データを遅延ロードするため、対応する get メソッドを呼び出すことによってロードがトリガーされるまで、フィールドは入力されません。

TestObject で setter/getter メソッドを使用するようにテスト コードを変更すると、予想どおり、同じ行が 2 回出力されます。

参照: OrientDB Object2RecordJavaBinding

于 2014-01-07T19:06:58.187 に答える