2012-07-04 2 views
1

У меня есть странная проблема с использованием поля UUID в классе.Поле UUID не хранится NeoDatis

Я использую NeoDatis для сохранения объектов в базе данных, и это работает нормально, за исключением того, что значение поля извлеченных экземпляров не равно тому, что было, когда я сохраняю объект.

В частности, наименьшиеSigBits и mostSigBits одинаковы в извлеченном экземпляре и в исходном, но поле «вариант» отличается!

Я предполагаю, что Neodatis не хранит поле вариантов, поскольку оно отмечено как переходное, но странно, что поле задается только функцией variant(), которая лениво вычисляет его, основываясь только на значениях из наименьших значений SigBits и mostSigBits , Имея эти два поля с одинаковым значением, я ожидал бы получить такое же значение и для поля варианта, но вместо этого получаю значение 2 в моем исходном объекте и 0 на моих сохраненных и извлеченных объектах.

Оба экземпляра разрешают одно и то же значение String, поэтому я мог бы пропустить проблему, сохранив строковое представление UUID, но я бы предпочел понять, что происходит не так.

EDIT:

Я написал тестовый класс, который воспроизведет проблему:

public class TestObj { 
    public UUID getId() { 
     return id; 
    } 

    private final UUID id = UUID.randomUUID(); 

    @Test 
    public static void storeAndRetrieve() { 
     TestObj o = new TestObj(); 
     ODB odb = ODBFactory.open("tested.db"); 
     try { 
      odb.store(o); 
     } finally { 
      odb.close(); 
     } 

     odb = ODBFactory.open("tested.db"); 
     try { 
      TestObj o2 = odb.<TestObj>getObjects(TestObj.class).getFirst(); 
      Assert.assertEquals(o2.getId().toString(), o.getId().toString()); 
      Assert.assertEquals(o2.getId(), o.getId()); /*this one fail!*/ 
     } finally { 
      odb.close(); 
     } 

    } 
} 

ответ

1

У меня была такая же проблема, но после обсуждения с Оливье (главный разработчик этого проекта) он дал мне решение: использование InstantiationHelper.

Он добавил несколько тестов в исходное дерево. Посмотрите на org.neodatis.odb.test.uuid.TestUUID.java в CVS-рекреаторе. В моем случае я использовал второе решение:

public void testWithFullInstantiationHelper() throws Exception { 
    String baseName = getBaseName(); 
    ODB odb = open(baseName); 

    ClassWithUUID o = new ClassWithUUID("t1", UUID.randomUUID()); 
    odb.store(o); 
    odb.close(); 
    odb = open(baseName); 

    // Sets the instantiation helper 
    ClassRepresentation uuidRepresentation = odb.getClassRepresentation(UUID.class); 
    uuidRepresentation.addFullInstantiationHelper(new FullInstantiationHelper() { 
     public Object instantiate(NonNativeObjectInfo nnoi) { 
      // retrieve uuid instance field values 
      AbstractObjectInfo[] aois = nnoi.getAttributeValues(); 
      // build the instance from the internal values 
      return new UUID((Long) aois[0].getObject(), (Long) aois[1].getObject()); 
     } 
    }); 

    Objects<ClassWithUUID> objects = odb.getObjects(ClassWithUUID.class); 
    assertEquals(1, objects.size()); 
    // check name and uuid 
    assertEquals(objects.getFirst().getName(), o.getName()); 
    assertEquals(objects.getFirst().getUuid(), o.getUuid()); 
    odb.close(); 
    deleteBase(baseName); 
} 
+0

Спасибо, Бруно. Я больше не работаю над этим проектом, но в любом случае надеюсь, что ваш ответ поможет будущим пользователям Neodatis. –

0

Вопрос заключается в том, что NeoDatis инициализирует переходные поля к нулю, а не -1.

Эти поля должны иметь следующие значения по умолчанию: version = -1; variant = -1; timestamp = -1; sequence = -1; node = -1; hashCode = -1;

NeoDatis действительно должен обрабатывать java.util.UUID как тип значения, а не объект.

Смежные вопросы