1

我尝试将 Eclipse Collection 的 LongArrayList ( https://www.eclipse.org/collections/ ) 与 Microstream 一起存储,但由于它的“items”字段是瞬态的,因此无法开箱即用。

所以我所做的是创建一个新类 PersistableLongArrayList ,如下所示:

public class PersistableLongArrayList extends LongArrayList {
    static BinaryTypeHandler<PersistableLongArrayList> provideTypeHandler() {
        return Binary.TypeHandler(PersistableLongArrayList.class,
            Binary.Field_int(
                "size", 
                list -> list.size, 
                (list, value) -> list.size = value
            ),
            Binary.Field(
                long[].class, "items", 
                list -> list.items, 
                (list, value) -> list.items = value
            )
        );
    } 
}

从存储实例加载时,项目字段现在不为空,但是如果我之后更改值并调用 storage.store(list),关闭数据库并重新启动它,则不会存储新值,仅正确存储大小。

我添加了一个非常简单的示例来显示此行为:

public class SimpleTest {
    private PersistableLongArrayList root;

    public static void main(String[] args) {
        try {
            SimpleTest t = new SimpleTest();
            // DB erstellen
            EmbeddedStorageManager storage = t.startDB();
            // modify the list
            t.root.add(t.root.size() + 1);
            storage.store(t.root);
            // stop DB
            t.stopDB(storage);
            // restart DB
            storage = t.startDB();
            // show root element
            System.out.println(t.root);
            // Observed behavior: list "grows" from s.th. like this: [1] to s.th. like this [1, 0, 0, 0] after several runs (Probably only size grows and is stored correctly and therefore the fields up to "size" are printed but empty)
            // Expected beahvior: list starts with [1] and grows to something like this [1, 2, 3, 4] after several runs
        } catch (Throwable t) {
            t.printStackTrace();
        } finally {
            System.exit(0);
        }
    }

    private EmbeddedStorageManager startDB() {
        EmbeddedStorageManager storageManager = EmbeddedStorage.start();
        if(storageManager.root() == null) {
            PersistableLongArrayList list = new PersistableLongArrayList();
            storageManager.setRoot(list);
            storageManager.storeRoot();
            root = list;
        } else {
            root = (PersistableLongArrayList)storageManager.root();
        }
        return storageManager;
    }

    private void stopDB(EmbeddedStorageManager storageManager) {
        storageManager.shutdown();
    }
}

可能我只是误解了如何正确使用自定义 BinaryHandler,但我现在不知道要更改什么。任何建议表示赞赏:)

亲切的问候,托马斯

4

1 回答 1

2

使用自定义 PersistenceEagerStoringFieldEvaluator 和 PersistenceFieldEvaluator 可以直接持久化 LongArrayList:

public class PersistenceFieldEvaluatorCustom implements PersistenceFieldEvaluator {

    @Override
    public boolean applies(final Class<?> entityType, final Field field) {

        //return true if field should be persisted, false if not
        if(entityType == org.eclipse.collections.impl.list.mutable.primitive.LongArrayList.class && field.getName().equals("items")) {
            return true;
        }

        //default: return false if field has the transient modifier
        return !XReflect.isTransient(field);
    }
}
public class PersistenceEagerStoringFieldEvaluatorCustom implements PersistenceEagerStoringFieldEvaluator {

    @Override
    public boolean isEagerStoring(final Class<?> t, final Field u) {

        //return true if field should be persisted at every store
        if(t == org.eclipse.collections.impl.list.mutable.primitive.LongArrayList.class && u.getName().equals("items")) {
            return true;
        }
        return false;
    }
}

设置:

final EmbeddedStorageManager s = EmbeddedStorage.Foundation()
                .onConnectionFoundation(
                        c->{ c.setFieldEvaluatorPersistable(new PersistenceFieldEvaluatorCustom());
                             c.setReferenceFieldEagerEvaluator(new PersistenceEagerStoringFieldEvaluatorCustom());
                        })
                .start();

此致

有关更多详细信息,请参见https://github.com/microstream-one/microstream/discussions/247

于 2021-09-21T12:21:34.313 回答