1

我在类中使用UUID字段时遇到了一个奇怪的问题。

我正在使用NeoDatis将对象持久保存到数据库,这工作正常,除了检索到的实例的字段值不等于我保存对象时的值。

特别是,在检索到的实例和原始实例中,leastSigBits 和 mostSigBits 是相同的,但“variant”字段不同!

我假设 Neodatis 不存储变量字段,因为它被标记为瞬态,但奇怪的是该字段仅由variant()函数设置,该函数仅根据来自 minimumSigBits 和 mostSigBits 字段的值懒惰地计算它。让这两个字段具有相同的值,我希望变量字段也能获得相同的值,但是我在原始对象中获得了 2 的值,而在我的存储和检索对象中获得了 0 的值。

两个实例都解析为相同的字符串值,因此我可以通过存储 UUID 的字符串表示来跳过该问题,但我更愿意了解发生了什么问题。

编辑:

我写了一个重现问题的测试类:

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

    }
}
4

2 回答 2

1

我遇到了同样的问题,但在与 Olivier(该项目的主要开发人员)讨论后,他给了我解决方案:使用InstantiationHelper

他在源代码树中添加了一些测试。查看CVS 存储库中的org.neodatis.odb.test.uuid.TestUUID.java。就我而言,我使用了第二种解决方案:

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);
}
于 2013-05-24T13:54:20.767 回答
0

问题是 NeoDatis 将瞬态字段初始化为零而不是 -1。

这些字段应具有以下默认值: version = -1; 变体 = -1; 时间戳=-1;序列=-1;节点=-1;哈希码 = -1;

NeoDatis 确实应该将 java.util.UUID 视为值类型而不是对象。

于 2013-01-22T18:51:27.443 回答