Using jetstreamDB as in-memory Database for Java

June 30th, 2018 by

JetstreamDB is a in-memory database engine for Java that claims to be built for ultra-high speed and the ability of managing complex data structures by storing real Java objects instead of serializing data structures to other database specific formats.

In the following short example I would like to demonstrate how to create and read items from such a database by building a small article management sample app.

Using jetstreamDB for Java

Using jetstreamDB for Java

 

Project Setup

First of all we’re adding some Maven repositories to our project’s pom.xml:

<repositories>
	<repository>
	  <id>jetstream-releases</id>
	  <url>https://maven.jetstream.one/maven2-public</url>
	  <releases>
		<enabled>true</enabled>
	  </releases>
	  <snapshots>
		<enabled>false</enabled>
	  </snapshots>
	</repository>
	<repository>
	  <id>jetstream-snapshots</id>
	  <url>https://maven.jetstream.one/maven2-public-snapshot</url>
	  <releases>
		<enabled>false</enabled>
	  </releases>
	  <snapshots>
		<enabled>true</enabled>
	  </snapshots>
	</repository>
</repositories>

Afterwards just need to add the following dependency:

<dependency>
  <groupId>com.jetstreamdb</groupId>
  <artifactId>jetstreamdb-embedded</artifactId>
  <version>1.0.0-beta1</version>
</dependency>

Sample Application

We’re now implementing a sample application to store and retreive some data from a jetstreamDB…

Root Entity

This is our aggregate, the root of our persisted data:

package com.hascode.tutorial;
 
import java.util.ArrayList;
import java.util.List;
 
public class RootData {
 
  private final List<Article> articles = new ArrayList<>();
 
  public List<Article> getArticles() {
    return articles;
  }
}

Article Entity

This is our article entity

package com.hascode.tutorial;
 
public class Article {
 
  private final String title;
 
  // constructor, getter, setter, tostring ommitted..
}

Command Line App

This is our command line app that allows us to create and list our articles:

package com.hascode.tutorial;
 
import com.jetstreamdb.JetstreamDBInstance;
import java.io.Console;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.List;
 
public class ArticleApp {
 
  private static final String USAGE = "Enter a command 'l': list, 'a': add, 'q': quit 'd': db info\n";
 
  private JetstreamDBInstance<RootData> db;
 
  public ArticleApp() {
    db = JetstreamDBInstance.New("my-articles-db ", RootData.class);
    Path databaseDirectory = Paths.get("").resolve("article-db");
    System.out.printf("creating database directory in %s%n", databaseDirectory.toAbsolutePath());
    db.configuration().properties().setStorageDirectory(databaseDirectory.toFile());
  }
 
  public static void main(String[] args) {
    new ArticleApp().run();
  }
 
  public void run() {
    prompt();
  }
 
  private void prompt() {
    Console console = System.console();
    System.out.println(USAGE);
    String command = console.readLine();
    switch (command) {
      case "q":
        System.out.println("quitting...");
        System.exit(1);
        break;
      case "l":
        List<Article> articles = db.root().getArticles();
        System.out.printf("%d articles found:%n", articles.size());
        articles.forEach(System.out::println);
        prompt();
        break;
      case "a":
        System.out.println("Please enter a title");
        String title = console.readLine();
        List<Article> update = db.root().getArticles();
        update.add(new Article(title));
        db.store(update);
        prompt();
        break;
      case "d":
        System.out.printf("basedir: %s, name: %s%n", db.configuration().getBaseDir(),
            db.configuration().name());
        prompt();
        break;
      default:
        System.out.println("invalid command");
        prompt();
    }
  }
 
}

Running the Application

Now we’d like to add and fetch some data from our application:

We may start the application using our IDE or using Maven in the command line like this:

mvn clean compile exec:java -Dexec.mainClass=com.hascode.tutorial.ArticleApp
[..]
                   `:osssssssso/.
            y+  .oy/.        `:oy/
            ho /h:              `sy`
            hddd/oooooooooooooooo+omdo.
           smmmoy+               d/dmmd/          JetstreamDB
          -mmmm+h/               h/dmmmh
          -mmmmh/y+`           .oy+mmmmd          Version 1.0.0-beta1
          -mmmmdy.:os+-.```.:oso-:dmmmmd
          :mh+- -yo. .:++o+/:``:so``/sdd
         :h/      .+so+//:/+oss/`     .oy.
        :d.   ``      `.:m-.`      ``   /d.
        h+    oo        .d`        +s    so
        d:    oo        .d` /oooo- +s    +y
        h/    oo        .d`        +s    +y
        /h----yo        `:         +y----h+
         sd/::yo                   +y::/ds
          :yo:so                   +s:oy/
            ./ho        .d`        oh/.
              so        .d`        +y
              oo        .d`        +y
              ohoooo+++/+m+/+++oooohy
              .ss+::/+shs/sho/:-:/ss.
       ``````````-:::-.`````-:///-`````````
       ````````````````````````````````````
            ``````````````````````````
creating database directory in /data/project/jetstream-tutorial/article-db
Enter a command 'l': list, 'a': add, 'q': quit 'd': db info
 
l
0 articles found:
Enter a command 'l': list, 'a': add, 'q': quit 'd': db info
 
a
Please enter a title
Some title
Enter a command 'l': list, 'a': add, 'q': quit 'd': db info
 
l
1 articles found:
Article{title='Some title'}
Enter a command 'l': list, 'a': add, 'q': quit 'd': db info
 
d
basedir: article-db, name: my-articles-db
Enter a command 'l': list, 'a': add, 'q': quit 'd': db info
 
a
Please enter a title
another one
Enter a command 'l': list, 'a': add, 'q': quit 'd': db info
 
l
2 articles found:
Article{title='Some title'}
Article{title='another one'}
Enter a command 'l': list, 'a': add, 'q': quit 'd': db info

Internal Structure

Having created those articles we can see that jetstreamDB has created the following files in the designated directory:

/article-db
├── channel_0
│   ├── channel_0_1.dat
│   └── transactions_0.sft
├── ObjectId.oid
├── PersistenceTypeDictionary.ptd
└── TypeId.tid

Tutorial Sources

Please feel free to download the tutorial sources from my Bitbucket repository, fork it there or clone it using Git:

git clone https://bitbucket.org/hascode/jetstreamdb-tutorial.git

Resources

Tags: , , ,

8 Responses to “Using jetstreamDB as in-memory Database for Java”

  1. Anonymous Says:

    Which Java version did you use. I tried with Java 10 – fresh clone from bitbucket – and it just crashed

  2. Micha Kops Says:

    I’ve used Java 8 (https://bitbucket.org/hascode/jetstreamdb-tutorial/src/master/pom.xml#lines-13).

    Which error did you encounter with Java 10? Some Illegal reflective access error?

  3. Marcel Says:

    No a class cast exception, I will try again with Java 8. Below my stack trace

    java.lang.ClassCastException: [B cannot be cast to [C

    at com.jetstreamdb.memory.Memory.accessChars(Memory.java:282)
    at com.jetstreamdb.persistence.binary.types.BinaryPersistence.storeStringsAsList(BinaryPersistence.java:1201)
    at com.jetstreamdb.persistence.binary.types.BinaryPersistence.storeStringsAsList(BinaryPersistence.java:1180)
    at com.jetstreamdb.persistence.binary.internal.BinaryHandlerPersistenceRootsImplementation.store(BinaryHandlerPersistenceRootsImplementation.java:144)
    at com.jetstreamdb.persistence.binary.internal.BinaryHandlerPersistenceRootsImplementation.store(BinaryHandlerPersistenceRootsImplementation.java:1)
    at com.jetstreamdb.persistence.binary.internal.AbstractBinaryHandlerNative.store(AbstractBinaryHandlerNative.java:1)
    at com.jetstreamdb.persistence.binary.types.BinaryStorer$Implementation.storeItem(BinaryStorer.java:450)
    at com.jetstreamdb.persistence.binary.types.BinaryStorer$Implementation.storeGraph(BinaryStorer.java:441)
    at com.jetstreamdb.persistence.binary.types.BinaryStorer$Implementation.store(BinaryStorer.java:325)
    at com.jetstreamdb.persistence.types.PersistenceManager$Implementation.store(PersistenceManager.java:163)
    at com.jetstreamdb.storage.types.StorageConnection.store(StorageConnection.java:132)
    at com.jetstreamdb.storage.types.EmbeddedStorageManager$Implementation.initialize(EmbeddedStorageManager.java:214)
    at com.jetstreamdb.storage.types.EmbeddedStorageManager$Implementation.start(EmbeddedStorageManager.java:141)
    at com.jetstreamdb.storage.types.EmbeddedStorageManager$Implementation.start(EmbeddedStorageManager.java:1)
    at com.jetstreamdb.storage.types.EmbeddedStorageManager.start(EmbeddedStorageManager.java:50)
    at com.jetstreamdb.storage.types.EmbeddedStorageManager.start(EmbeddedStorageManager.java:41)
    at com.jetstreamdb.JetstreamDBInstance.createAndStartStorageManager(JetstreamDBInstance.java:462)
    at com.jetstreamdb.JetstreamDBInstance.start(JetstreamDBInstance.java:402)
    at com.jetstreamdb.JetstreamDBInstance.root(JetstreamDBInstance.java:284)
    at net.tangly.erp.crm.db.CrmRoot.addFoo(CrmRoot.java:55)
    at net.tangly.erp.crm.db.CrmRootTest.testCrmRoot(CrmRootTest.java:12)

  4. Marcel Says:

    Java 8 works fine. It seems that the library is not compatible with Java 10 or Java 11. Thanks for the hint.

  5. Micha Kops Says:

    You’re welcome! Thanks for keeping me up-to-date :)

  6. ChrisPac Says:

    With using Java8, I get the following exception when starting the unchanged example:

    Exception in thread “main” java.lang.NoClassDefFoundError: com/jetstreamdb/collections/types/XGettingCollection
    at com.hascode.tutorial.ArticleApp.(ArticleApp.java:17)
    at com.hascode.tutorial.ArticleApp.main(ArticleApp.java:24)
    Caused by: java.lang.ClassNotFoundException: com.jetstreamdb.collections.types.XGettingCollection
    at java.net.URLClassLoader.findClass(Unknown Source)
    at java.lang.ClassLoader.loadClass(Unknown Source)
    at sun.misc.Launcher$AppClassLoader.loadClass(Unknown Source)
    at java.lang.ClassLoader.loadClass(Unknown Source)
    … 2 more

  7. ChrisPac Says:

    Oh, it was just a corrupt JAR file. Just removed it from local repository and updated maven – everything fine!

  8. Micha Kops Says:

    Hi, I’m glad that it’s working for you now, thanks for the update! :)

Leave a Reply

Please note, that no personal information like your IP address is stored and you're not required to enter you real name.

Comments must be approved before they are published, so please be patient after having posted a comment - it might take a short while.

Please leave these two fields as-is:
Search
Categories