1

I've taken the example from https://github.com/microstream-one/examples/blob/master/loading/src/main/java/one/microstream/sampler/loading/Main.java

I've modified it to add new objects on each run but it only stores the results of the first run. Subsequent runs show the original two, and the two added in the current run, but not those added in other runs.

How do I get it to store the new additions so they are restored in the next run?

package example;

import one.microstream.storage.embedded.types.EmbeddedStorage;
import one.microstream.storage.embedded.types.EmbeddedStorageManager;

import java.util.ArrayList;
import java.util.List;
import java.util.UUID;

public class Main {
    public static void main(String[] args) {
        // Init storage manager
        final EmbeddedStorageManager storage = EmbeddedStorage.start();
        //storage.setRoot(null);

        MyRoot root;
        //if storage.root() returns null no data have been loaded
        //since there is no existing database, let's create a new one.
        if (storage.root() == null) {
            System.out.println("No existing Database found, creating a new one:");

            root = new MyRoot();
            storage.setRoot(root);
        }
        //storage.root() is not null so we have loaded data
        else {
            root = (MyRoot) storage.root();
            System.out.println("Existing Database found: " + root.myObjects.size());
        }

        root.myObjects.add(new MyData(UUID.randomUUID().toString()));
        root.myObjects.add(new MyData(UUID.randomUUID().toString()));
        storage.storeRoot();

        root.myObjects.forEach(System.out::println);
        storage.shutdown();
    }

    public static class MyRoot {
        public List<MyData> myObjects = new ArrayList<>();
    }

    public static class MyData {
        private String name;
        private int intValue;

        public MyData(final String content) {
            super();
            this.name = content;
        }

        public String getName() {
            return this.name;
        }

        public void setName(final String name) {
            this.name = name;
        }

        public int getIntegerValue() {
            return this.intValue;
        }

        public void setIntValue(final int integerValue) {
            this.intValue = integerValue;
        }

        @Override
        public String toString() {
            return this.name + " value: " + this.intValue;
        }
    }
}

I'm using these dependencies:

        <dependency>
            <groupId>one.microstream</groupId>
            <artifactId>microstream-storage-embedded</artifactId>
            <version>07.00.00-MS-GA</version>
        </dependency>
        <dependency>
            <groupId>one.microstream</groupId>
            <artifactId>microstream-storage-embedded-configuration</artifactId>
            <version>07.00.00-MS-GA</version>
        </dependency>

1 Answers1

1

I found the reason. I thought the storeRoot() method was recursive and would save changes to the root.myObjects. It turns out not to be so, and I have to explicitly call store(root.myObjects). Also, when modifying the objects themselves, I have to call store(dataObject) This is the modified code, with additional example of modifying objects:

public static void main(String[] args) {
    // Init storage manager
    final EmbeddedStorageManager storage = EmbeddedStorage.start();
//        storage.setRoot(null);
//        storage.storeRoot();

    MyRoot root;
    //if storage.root() returns null no data have been loaded
    //since there is no existing database, let's create a new one.
    if (storage.root() == null) {
        System.out.println("No existing Database found, creating a new one:");

        root = new MyRoot();
        storage.setRoot(root);
        storage.storeRoot();
    }
    //storage.root() is not null so we have loaded data
    else {
        root = (MyRoot) storage.root();
        System.out.println("Existing Database found: " + root.myObjects.size());
        root.myObjects.forEach(System.out::println);

        root.myObjects.forEach(o -> {
            o.setIntValue(root.myObjects.size());
        });
        storage.storeAll(root.myObjects);
    }

    root.myObjects.add(new MyData(UUID.randomUUID().toString()));
    root.myObjects.add(new MyData(UUID.randomUUID().toString()));
    storage.store(root.myObjects);

    storage.shutdown();
}
  • Correct, you can use recursive behaviour when storing objects using the eager storer https://docs.microstream.one/manual/storage/storing-data/lazy-eager-full.html. But the default storer is not working recursively, see https://docs.microstream.one/manual/storage/storing-data/index.html and https://foojay.io/today/microstream-part-3-storing-data/ – Rudy De Busscher Aug 24 '22 at 06:27