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 =
        applicationContext.newPersistenceContext();

AuthorTopiaDao authorDao =
        persistenceContext.getAuthorDao();

BookTopiaDao bookDao = persistenceContext.getBookDao();

// now, we are ready to work

applicationContext.close();

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
Assert.assertFalse(platon.isPersisted());

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)
Assert.assertTrue(platon.isPersisted());

You now just have to call

persistenceContext.commit();

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");
theRepublic.setAuthor(platon);
Assert.assertFalse(theRepublic.isPersisted());
bookDao.create(theRepublic);

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,
                ImmutableSet.of(
                        "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.setIsbn("123456789");
bookDao.update(book);

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

// commit both changes
persistenceContext.commit();

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

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