0

db4oとJODAを使用していますが、DateTimeオブジェクトの保存/受信で問題が発生しました。少なくともそれが問題だったと思います。

私のデータモデルは次のようになります。

DataFile.class
    enum FileType {...}
    further attributes... (primitve data types)

Product.class extends DataFile.class
    enum ProductType {...}
    further attributes... (primitve data types)

KindOfProduct.class extends Product.class
    DateTime time
    further attributes... (primitve data types)

KindOfProductオブジェクトを作成し、EmbeddedDatabaseに保存しています。これらのオブジェクトをクエリするために、私はSODAを使用しており、Evaluationを実装するDateTimeComparison.classを取得しました。DateTime以外のフィールドのクエリは正常に機能しますが、DateTimeクエリは失敗します。奇妙なことに、データベースに格納されているオブジェクトの数に関係なく、evaluateメソッドが1回だけ呼び出されます。候補のincludeメソッドはtrueで呼び出されますが、候補はObjectSetに含まれていません。したがって、どこかでエラーが発生し、db4oが例外をスローせずに終了するように見えます(これは、SODAクエリを評価するための既知の問題です)。Eclipse用のObjectManagerEnterpriseプラグインを使用したクエリは失敗します。「結果を表示できません」というエラーメッセージが表示されます。

評価インターフェイスを正しく実装したことは間違いありません(DateTimeとは異なるデータ型に対して同様のことを行ったので、正常に機能します)。他のプロジェクトでは実装する必要がなかったので、DateTimeオブジェクトを格納するためにTypeHandlerを実装する必要があるとは思いません(その場合はネイティブクエリを使用していましたが、それは重要ではないと思います)。

それで、どのように探すかについてのアイデアはありますか?既知の落とし穴はありますか?

編集:私の評価クラスのコード

import org.joda.time.DateTime;

import com.db4o.query.Candidate;
import com.db4o.query.Evaluation;

public class DateTimeComparison implements Evaluation {

protected enum Operator {

    GREATER, SMALLER, EQUAL

}

private Operator operator = null;
private DateTime value = null;

public DateTimeComparison(String operator, DateTime value) {

    if (operator.equals(">")) {
        this.operator = Operator.GREATER;
    } else {
        if (operator.equals("<")) {
            this.operator = Operator.SMALLER;
        } else {
            this.operator = Operator.EQUAL;
        }
    }
    this.value = value;

}

public void evaluate(Candidate candidate) {

    DateTime dateTime = (DateTime) candidate.getObject();

    boolean match = false;
    switch (operator) {
    case GREATER:
        match = dateTime.compareTo(value) > 0;
        break;
    case SMALLER:
        match = dateTime.compareTo(value) < 0;
        break;
    case EQUAL:
        match = dateTime.compareTo(value) == 0;
        break;
    }
    candidate.include(match);
    System.out.println(match);

}

}
4

2 に答える 2

0

評価コード/クラスを表示できますか?

さもないと:

はインデックスを使用できないため、評価が「遅く」なることに注意してください。大規模なデータ セットでは、これが問題になります。

問題を回避するための最も信頼できるが醜い方法は、格納されたオブジェクトに通常の Java Date を格納することです。そして、getter/setter で Date フィールドを JodaTime DateTime に変換します。また、クエリも同様です。

タイプハンドラーへ: 理論的には、それを機能させることができます。DateTime を格納するだけの単純な型ハンドラーは、おそらくそれほど難しくありません。しかし、インデックスのような高度な機能の場合、タイプハンドラーは悪夢です (ドキュメントがない、内部データ構造にキャストする必要があるなど)。

于 2012-06-08T00:39:35.317 に答える
0

テスト ケースを作成しようとしているときに、エラーが見つかりました。問題は評価ではなく、クエリの制約を構築する方法でした。私は、これらの制約を txt ファイルから読み取ることにより、動的に構築する方法に取り組んでいます。制約がどの順序でリンクされているかに注意を払う必要があるという事実については、私は知りませんでした。例: (A and B) or C は A and (B or C) と等しくありません。そのため、構築したいクエリを表現していない制約になってしまいました。

現在、制約を定義してから、逆ポーランド記法を使用してそれらをリンクする方法を宣言しているため、括弧を気にする必要はありません。これはかなりうまくいくようです...

于 2012-06-11T13:55:30.660 に答える