Skip to content
This repository has been archived by the owner on Oct 6, 2020. It is now read-only.

DesignNotePersistence

snommensen edited this page Apr 11, 2011 · 11 revisions

Design Note: Persistence

The persistence-related code resides in the "persistence" module. The module forms a persistence layer, which can be used by our GWT-RPC services.

The persistence module works with three types of classes:

  • BOs (Business Objects; Plain old Java objects that define a structure to be stored by Hibernate)
  • DAOs (Data Access Objects; Those objects manage the BOs, e.g. persist and find them)
  • Services (transactional service layer to be used by the GWT client)

We distinguish between Data Transfer Objects (DTO) and Business Objects (BO). Our DTOs are located in the "shared" module. DTOs can be used in the "client". Our persistent objects are called BOs aka business objects; (*Bo.java). The BOs are the objects with the Hibernate annotations. Internally, "persistence" only works with BOs. The "persistence" layer only returns and accepts DTOs in its interface. This way we achieve a clear separation of persistence and the rest of our modules.

As persistence is a very general task (cross-cutting concept), architecturally we need to place it underneath our taks-oriented services. This way our GWT-RPC services, e.g. TestbedConfigurationService, can utilize persistence, but at the same time persistence cannot be directly used by the client.

Transaction Management

We are using Spring transaction management. Without this a developer you would have to use the HibernateUtil and open and close you transactions manually. This means you have to manually make sure (e.g. using a finally-block) that your transaction is closed, which could be an error-prone programming task. Spring offers annotation-based transaction management with the @Transactional annotation. Internally, this is done with aspect oriented programming (AOP), but this is transparent to the developer.

    @Override
    @Transactional(readOnly = true)
    public TestbedConfiguration loadTestbedConfiguration(final Integer id) {
        Preconditions.notNullArgument(id, "Argument 'id' is null!");

        LOGGER.info("loadTestbedConfiguration( " + id + " )");

        final TestbedConfigurationBo bo = testbedConfigurationDao.findById(id);
        Preconditions.notNull(bo, "TestbedConfiguration with id '"
                + id
                + "' does not exist!");
        return dozerBeanMapper.map(bo, TestbedConfiguration.class);
    }

This is an example of a read-only transaction implemented as a method in our PersistenceService. What the @Transactional notation does is opening a transaction when the method is called and then closing the transaction when the method is finished. Internally, this is done with Aspect Oriented Programming (AOP). This eliminates the need for the developer to manually open and close transactions and therefore reduces the potential risk of leaking transactions.

About Layers