Create a persistence context and get a DAO

Here is a boilerplate code to start playing with ToPIA, you will find it in the sample project.

Map<String, String> configuration = new HashMap<String, String>();

MyLibraryTopiaApplicationContext applicationContext =
        new MyLibraryTopiaApplicationContext(configuration);

MyLibraryTopiaPersistenceContext persistenceContext =

AuthorTopiaDao authorDao =

BookTopiaDao bookDao = persistenceContext.getBookDao();

// now, we are ready to work


As you can see, being ready to work with ToPIA is pretty straightforward.

DAO usage

Create entities (a.k.a. the C in CRUD)

Author platon = new AuthorImpl();
platon.setName("Platon"); // Yeah, Platon is french for Plato, the very first greek troll

As you can see, for each entities, you are provided with an interface (Stuff), and its implementation (StuffImpl) as a plain old Java Bean.

You can always test whether an entity is persisted or not.

authorDao.create(platon); // now do create (a.k.a SQL INSERT)

You now just have to call


and the database will have, in its ‘author’ table, a row with a technical id.

Let’s see some other ways to create Book entities:

Book theRepublic = new BookImpl();
theRepublic.setName("La République");

Another way to create an entity, in one line:

Book gorgias = bookDao.create(
        Book.PROPERTY_AUTHOR, platon,
        Book.PROPERTY_NAME, "Gorgias");

… or given a map of the properties

Map<String, Object> bookProperties = new HashMap<String, Object>();
bookProperties.put(Book.PROPERTY_AUTHOR, platon);
bookProperties.put(Book.PROPERTY_NAME, "Le Banquet");
Book leBanquet = bookDao.create(bookProperties);

Retrieve entites (a.k.a. the R in CRUD)

All simple operations are available on the DAO.

List<Book> allBooks = bookDao.findAll();
long booksCount = bookDao.count();
List<Book> allBooksInAlphabeticalOrder = bookDao.newQueryBuilder().setOrderByArguments(Book.PROPERTY_NAME).findAll();

Most of the time, we need to find a single entity among the whole database:

Book book = bookDao.forNameEquals("La République").findUnique();

If you are not sure that this particular book is available, you may use.

Book bookOrNull = bookDao.forNameEquals("La République").findUniqueOrNull();
Optional<Book> bookOptional = bookDao.forNameEquals("La République").tryFindUnique();

If you’re not familiar with Optionals, it’s just convenient way to represent the possibility of an absent result: it’s a compile-safe, type-safe way to handle null values. If you prefer getting null, you may use findXXXOrNull instead of tryFindXXX.

If you want the first one among multiple results, you should use:

Book firstBook = bookDao.newQueryBuilder().setOrderByArguments(Book.PROPERTY_NAME).findFirst();

Every methods of this API starting by “try” or ending by “OrNull” handle when no results are returned. Otherwise, an exception will be raised.

Now, let’s do a bit of filtering.

Optional<Book> aBookObtainedViaComplexQuerying = bookDao.newQueryBuilder()
        . addEquals(Book.PROPERTY_AUTHOR, platon)
        . addIn(Book.PROPERTY_NAME,
                        "La République", "Le banquet"
        . setOrderByArguments(Book.PROPERTY_ISBN)
        . tryFindFirst();

This example should be self-explanatory: among the books authored by platon and being titled “La République” or “Le banquet”, we want the first one of the results sorted by the ISBN order. It’s a tryFind… so if there is no result at all, we will just get an Optional.absent().

Update entities (a.k.a. the U in CRUD)

Book book = bookDao.forNameEquals("La République").findUnique();

Book anotherBook = bookDao.forNameEquals("Le Banquet").findUnique();

// commit both changes

Delete entities (a.k.a. the D in CRUD)

Book book = bookDao.forNameEquals("La République").findUnique();