microstream
microstream copied to clipboard
Cannot store any entry in map
Environment Details
- MicroStream Version:
- JDK version: JDK 17
- OS: Linux
- Used frameworks: None
Describe the bug
Cannot store any entry in map. When loading it after restart it is always empty. Following the same pattern with a list does not show the problem.
Here is code snippet showcasing issue.
@Test
void test() {
EmbeddedStorageManager storageManager = EmbeddedStorage.start(Paths.get("/home/my-data"));
PerfData root = getRoot(storageManager);
if (root.getUsers() == null) {
root.setUsers(new LinkedList<>());
}
if (root.getUserData() == null) {
root.setUserData(new HashMap<>());
}
System.out.println("User ? "+root.getUsers().size());
PerfData.UserData xxx = new PerfData.UserData("xxx");
root.getUserData().put("abc", xxx);
storageManager.store(root.getUserData());
root.getUsers().add(xxx);
storageManager.store(root.getUsers());
storageManager.storeRoot();
storageManager.shutdown();
}
private PerfData getRoot(EmbeddedStorageManager storageManager) {
if (storageManager.root() == null) {
PerfData perfData = new PerfData();
storageManager.setRoot(perfData);
storageManager.storeRoot();
storageManager.store(perfData.getUserData());
log.info("Generating new root for data.");
return perfData;
} else {
PerfData root = (PerfData) storageManager.root();
log.info("Reusing data. Already {} users generated", root.getUserData().keySet().size());
return root;
}
}
@Getter
@Setter
class PerfData {
Map<String, UserData> userData = new HashMap<>();
List<UserData> users = new LinkedList<>();
String name = UUID.randomUUID().toString();
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
record UserId(String userId) {
}
record UserData(String name) {
}
}
After some investigation, it has the same problem when storing a list build using Collections.synchronizedList().
The problem is that no error is raised. There should be at least some warnings or stuff that the map/list cannot be saved/loaded.
Hi @ghilainm
I did run your code and do not have any issues. When I run it the second time, I get this log message
Reusing data. Already 1 users generated
So can you assemble a project that shows the error so that we can run it and test it further.
Thx Rudy
Some additional comments about your code
storageManager.storeRoot();
storageManager.store(perfData.getUserData());
The call to .store()
here is not needed as the .storeRoot()
method stored everything already on disk. The rule is store what is changed but nothing is changed between the call to .storeRoot()
and .store()
.
Also this call to .storeRoot()
is not needed.
storageManager.storeRoot();
storageManager.shutdown();
Since you did not change the Root instance itself. You should only call .storeRoot()
whenever you perform .setRoot()
.