This project has retired. For details please refer to its Attic page.
Apache Marmotta - KiWi Triplestore

KiWi Triplestore

The heart of the KiWi triple store is the KiWiStore storage backend. It implements a OpenRDF Notifying Sail on top of a custom relational database schema. It can be used in a similar way to the already existing (but now deprecated) OpenRDF RDBMS backends. The KiWi triple store operates almost directly on top of the relational database, there is only minimal overhead on the Java side (some caching and result transformations). Each OpenRDF repository connection is a database connection, and each repository result is a database cursor (so it supports lazy fetching when iterating over the result).

Maven Artifact

To use the KiWiStore, include the following artifact in your Maven build file:

<dependency>
    <groupId>org.apache.marmotta</groupId>
    <artifactId>kiwi-triplestore</artifactId>
    <version>3.3.0</version>
</dependency>

Code Usage

In your code, creating a KiWi triple store works mostly like other OpenRDF backends. The only additional data that is required are the JDBC connection details for accessing the database (i.e. database type, database URI, database user and database password) and how to store inferred triples or triples without explicit context. You can create a new instance of a KiWi store as follows:

String defaultContext  = "http://localhost/context/default";
String inferredContext = "http://localhost/context/inferred";
KiWiDialect dialect    = new H2Dialect();
KiWiStore store = new KiWiStore("test",jdbcUrl,jdbcUser,jdbcPass,dialect, defaultContext, inferredContext );
Repository repository = new SailRepository(store);
try {
    repository.initialize();

    // get a connection and perform operations as usual
    RepositoryConnection con = repository.getConnection();
    try {
        con.begin();
        // do stuff...
        con.commit();
    } finally {
        con.close();
    }
} catch (RepositoryException e) {
    // handle exception
} finally {
    repository.shutdown();
}

Note that there are some “uncommon” parameters, most notably the defaultContext and inferredContext:

  • defaultContext is the URI of the context to use in case no explicit context is specified; this changes the default behaviour of OpenRDF a bit, but it is the cleaner approach (and more efficient in the relational database because it avoids NULL values)
  • inferredContext is the URI to use for storing all triples that are inferred by some reasoner (either the KiWi reasoner or the OpenRDF RDFS reasoner); this is also a different behaviour to OpenRDF; we use it because the semantics is otherwise not completely clear in case an inference was made based on the information stemming from two different contexts
  • dialect specifies the dialect to use for connecting to the database; currently supported dialects are H2Dialect, PostgreSQLDialect and MySQLDialect; note that the MySQL JDBC library is licensed under LGPL and can therefore not be shipped with Apache Marmotta

We plan to add support for additional databases over time.

Performance Considerations

Additionally, there are some things to keep in mind when using a KiWi triple store (all of them are good coding practice, but in KiWi they also have performance implications):

  • if you are interested in good performance (production environments), use a proper database (e.g. PostgreSQL>=9.4)!
  • a RepositoryConnection has a direct correspondence to a database connection, so it always needs to be closed properly; if you forget closing connections, you will have resource leakage pretty quickly
  • all operations carried out on a repository connection are directly carried out in the database (e.g. inserting triples); the database connection is transactional, i.e. changes will only be available to other transactions when the commit() method is called explicitly; it is therefore good practice to always commit or rollback a connection before closing it
  • a RepositoryResult has a direct correspondence to a database ResultSet and therefore to a database cursor, so like with connections, it needs to be closed properly or otherwise you will have resource leakage
  • the value factory of the KiWi Store maintains its own, separate database connection for creating and retrieving RDF values; any newly created values are committed immediately to the database to make sure they are available to other transactions
  • the database tables will only be created when repository.initialize() is called; if the tables already exist, initialization will check whether a schema upgrade is required and automatically do the upgrade if needed
  • the repository must be explicitly shutdown when it is no longer needed, or otherwise it will keep open the database connection of the value factory as well as the internal connection pool