2012-06-07 7 views
0

db4o 및 JODA를 사용하고 있고 DateTime 객체를 저장/수신하는 데 문제가 있습니다. 적어도 그것이 문제라고 생각합니다.DB4O에서 JODA DateTime을 쿼리하는 SODA

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) 

I'am 만드는 KindOfProduct 오브젝트를하고 EmbeddedDatabase에 저장 :

내 datamodell는 다음과 같이 꽤 많이 보인다. 이러한 개체를 쿼리하려면 SODA를 사용하고 평가를 구현하는 DateTimeComparison.class가 있어야합니다. DateTime 이외의 필드에 대한 쿼리는 정상적으로 작동하지만 DateTime 쿼리가 실패합니다. 이상하게도, 데이터베이스에 얼마나 많은 객체가 저장되어 있는지에 관계없이 evaluate 메소드는 단지 한 번 호출됩니다. candidate의 include 메소드가 과 함께 호출되지만 후보는 ObjectSet에 포함되지 않습니다. 따라서 어쨌든 오류가 발생하고 db4o가 예외를 throw하지 않고 종료 된 것처럼 보입니다 (SODA 쿼리를 평가하는 데 알려진 문제, 모양으로 보아 ). Eclipse 용 Object Manager Enterprise 플러그인으로 질의하는 것이 실패합니다. 나는 "결과를 표시 할 수 없습니다"라는 오류 메시지가 나타납니다.

Evaluation 인터페이스를 올바르게 구현했음을 확신합니다. 에 대해 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); 

} 

} 

답변

0

당신이 당신의 평가 코드/클래스를 게재 할 수 있습니까?

그렇지 않으면 다음 인덱스를 사용할 수 없기 때문에 평가는, '느린'될 것

참고. 대용량 데이터 세트에서는 이것이 문제가됩니다.

정기적 인 Java Date를 저장 객체에 저장하는 가장 신뢰할 수 있지만보기 흉한 방법입니다. 그리고 getters/setter의 Date 필드를 JodaTime DateTime으로 변환합니다. 그리고 쿼리도 마찬가지입니다.

typehandler에게 : 이론적으로 당신은 그것을 작동하게 할 수 있습니다. DateTime을 저장하는 단순한 타입 핸들러는 그다지 어렵지 않을 것입니다. 하지만 인덱스와 같은 고급 기능의 경우 유형 핸들러는 악몽입니다 (문서가 없으며 내부 데이터 구조에 항목을 캐스팅해야 함).

+0

몇 가지 코드를 추가했습니다. 이상한 점은 println에 도달했기 때문에 구현에 문제가 없다는 것입니다. 또한 DateTime을 long으로 저장하는 타입 핸들러를 추가하려고 시도했지만 도움이되지 않았습니다 ... – suez

+0

흠, 괜찮아 보입니다. 작은 실례를 게시 할 수 있습니까? 그게 나처럼 버그 같아. – Gamlor

0

테스트 케이스를 만들려고하는 중에 실수를 발견했습니다. 문제는 평가가 아니라 쿼리에 대한 제약 조건을 구축하는 방법이었습니다. 이러한 제약 조건을 동적으로 작성하는 방법을 txt 파일에서 읽는 방법으로 작업하고 있습니다. 나는 제약 조건이 어느 순서로 연관되어 있는지주의를 기울여야한다는 사실을 알지 못했다. 예 : (A 및 B) 또는 C가 A 및 (B 또는 C)와 같지 않음. 그래서 저는 구축하고자하는 쿼리를 대표하지 않는 제약으로 끝 맺었습니다.

이제 구속 조건을 정의한 후 리버스 폴란드어 표기법을 사용하여 구속 조건을 선언해야하므로 대괄호를 신경 쓸 필요가 없습니다. 이것은 꽤 잘 작동하는 것 같습니다 ...