EclipseStore – Storing more complex data structures

How to store complex data structures using EclipseStore? Are there any restrictions? How can you work more efficiently on such structures? We will now get to the bottom of these questions here.

In the first part of my series, I showed how to prepare EclipseStore for use in a project. We also initialized the StorageManager and saved, modified and deleted the first data. But what about more complex structures? Can you use inheritance? To do this, we will now create a small class model.

First, let’s look at what inheritance looks like. To do this, we take an interface called BaseInterfaceA, an implementation BaseClassA and a derivative LevelOneA. We will now try to save this and see how it behaves depending on the input when saving.

Here is the listing of the classes and interfaces involved. Since we already saw in the first part that the implementation variant has no influence, I will use a standard implementation regarding getters and setters or the constructors.

Case I: Direct saving of the respective classes

The entities are packed directly into a list and saved in the first case. As we can see, there are no special features here. This is the same case as the first article. The output of the printElements method is exactly what we expected.

console output:

LevelOneA{valueOneA=’levelOneA – 01′}

LevelOneA{valueOneA=’levelOneA – 02′}

LevelOneA{valueOneA=’levelOneA – 03′}

 ==========

Case II: Save as a base class

Now, let’s consider the case where a class is passed to the StorageManager for storage as one of its base classes. In this case, the LevelOneA class is passed as the base class BaseClassA. It should be noted that this primary type was also used when defining the root list.

The output again meets our expectations.

LevelOneA{valueOneA=’levelOneA – 01′}

LevelOneA{valueOneA=’levelOneA – 02′}

LevelOneA{valueOneA=’levelOneA – 03′}

 ==========

Case II: Saving an implementation as an interface

Now let’s move on to the case in which we proceed via the interface. There are no problems here either. Everything behaves as expected.

The output on the console is still unchanged.

LevelOneA{valueOneA=’levelOneA – 01′}

LevelOneA{valueOneA=’levelOneA – 02′}

LevelOneA{valueOneA=’levelOneA – 03′}

 ==========

Case IV: Saving a mixed list via a common interface

Now if we define a list of type BaseInterfaceA as root and then add instances of different implementations. How does EclipseStore behave during the save process? To make a long story short, it works as intended. All instances are stored neatly after deployment. So we have no loss of information.

The console output will then look like this.

LevelOneA{valueOneA=’levelOneA – 01′}

BaseClassA{valueBaseA=’BaseClassA – 02′}

LevelOneA{valueOneA=’levelOneA – 03′}

 ==========

Storing lists, trees and graphs

Now that we’ve looked at whether inheritance is supported as much as we hoped, we’re getting to the point where we can start thinking about the data structures themselves. We have seen that simple entities and lists of entities are relatively easy for EclipseStore. Now, let’s go one step further and look at trees and graphs.

Storing of trees

In computer science, we understand a tree to be a data structure that can have branches but does not contain any cycles. This makes them a special form of graphs, just as lists are a special form of trees. So, let’s come to a tree implementation in which a node can have two child nodes. Of course, you can also build this structure with n child nodes, but this will not bring any added value in our case. If we create such a tree and give the root node to the StorageManager, we can save this tree without any further action. Modifying individual elements also works as usual. You can also change the desired segment and save on this or any higher-level piece.

Output to the console (subsequently formatted for readability):

Node{id=’rootNode’, 

leftNode=Node{id=’Root-L’, 

leftNode=Node{id=’Root-L-L’, 

leftNode=null, 

rightNode=null

}, 

rightNode=null

}, 

rightNode=Node{id=’Root-R’, 

leftNode=Node{id=’Root-R-L’, 

leftNode=null, 

rightNode=null

}, 

rightNode=Node{id=’Root-R-R’, 

leftNode=null, 

rightNode=null

}

}

}

Storing graphs

Unfortunately, you don’t just have to deal with lists and trees. Complex data models often have cycles. This can come about, for example, through bidirectional relationships. Unwanted cycles can also arise in a model if it grows over time and is repeatedly expanded. Whether these cycles are tightly or loosely coupled plays a minor role. The following example creates a chart that contains multiple cycles. Can the diagram then be saved, modified and loaded? Does EclipseStore recognize these structures and can resolve or break the loops?

In this example, the graph consists of nodes of the GraphNode class. This class contains an attribute of type String to store an ID. There is also a reference to the parent node and a list of child nodes. This means you can now create any nested chart you want.

In this case, the graphic looks like this.

The node rootNode is passed to the StorageManager as root and saved. A subsequent loading of the root results in the previously created graph.

As we can see from this example, EclipseStore can store graphs without any problems. Cycles are acceptable here.

Conclusion:

We have now seen that EclipseStore can store any data structure in its entirety; lists, trees and graphs are not a limitation. This allows us to create the data model independently of the persistence layer. This is a possibility that I have always been looking for in the last 20 years of my Java activities.

We will now deal with the intricacies of EclipseStore in the following parts. It remains exciting.

Happy coding

Sven

Leave a Reply