DAO Pattern

Abstracts from any direct type of database or persistence mechanism. Provides specific operations without exposing details of the database.

Componentized DAO Pattern

PerfectJPattern's componentized version of the DAO Pattern provides the following advantages:

  • Fine-grained multi-level design: Pure JPA-based DAO provides the building block to create a more specialized and feature-rich DAO that exploits non-JPA standard features. Richer functionality proportionally correspond to higher dependency requirements e.g. users able to afford Hibernate dependency can take advantage of the full IGenericDao implementation while those staying at pure JPA take advantage of an IBaseDao implementation
  • Abstract separation of read-only DAO: Provides a read-only abstract view of the DAO implementation that allows building read-only data layer API with ease i.e. exposing only IBaseReadOnlyDao or IGenericReadOnlyDao. Another relevant use-case is mapping database views to Model objects where the DAO should not allow changes to the underlying views. This is a simple but generally overlooked concept.
  • High Reusability: users are relieved from re-implementing DAOs and thus stay away from the DAO-per-model anti-pattern. One single DAO implementation is reused for all models
  • Client code simplicity: Client code stays the simplest as it will use the same set of PerfectJPattern's DAO interfaces in all contexts. Choosing one ORM implementation over another is just a matter of switching to the correct Abstract Factory e.g. JpaDaoFactory, HibernateDaoFactory, etc. All concerns related to:
    • Session or EntityManager Factory creation or JNDI lookup and closing
    • Session or EntityManager access and handling
    • Transaction lookup, access and handling
    are implemented and encapsulated within the DAO framework with sensitive defaults. There is no longer the need to copy and paste Util classes back and forth
  • High Portability: the same DAO implementation is reused in many different contexts e.g. JPA or non-JPA and different target platforms CMP or Java SE. All incompatibilities affecting DAO for JPA or DAO for Hibernate e.g. EntityManager vs Session, EntityTransaction vs Transaction, Query, etc are resolved via PerfectJPattern's componentized Adapter. PerfectJPattern offers these two abstract base implementations for integration with EJB:
    • AbstractJpaManagedBaseDao: extends JpaBaseDao and automatically integrates with your EJB EntityManager/Session lifecycle providing reusable IBaseDao implementation
    • AbstractHibernateManagedGenericDao: extends HibernateGenericDao and automatically integrates with your EJB EntityManager/Session lifecycle providing reusable IGenericDao implementation
  • High productivity: SpringGenericDao inspired by the article Don't repeat the DAO, provides automatic implementation of user-defined custom DAO interfaces (subtype of IGenericDao) that map to adhoc named queries. PerfectJPattern Spring sub-module ships with a reusable genericDao-applicationContext.xml that does all necessary wiring to get the automatic mapping working. The bit of switching to more specific Session or Transaction strategies and Factories or definition of custom DAO interfaces is project-specific and need to be done by the user. Please see the Spring example code below.

Please note that while PerfectJPattern goal is to maximize the quality of the client code i.e. maintainability, reusability, productivity, portability; the configurations and mappings that are framework-specific need to be provided by the user. Users can checkout PerfectJPattern examples and tests for:
  • Example JPA configurations (using OpenJPA as provider) persistence.xml and ORM in configuration orm.xml
  • Creating a many-to-many ORM Hibernate relation Customer-*Order*-Product see Example.hbm.xml
  • Configuring Spring to define custom DAO interfaces and injecting those to a LocalDaoFactory see example-applicationContext.xml

UML Class Design

JPA Example targeting EJB (tested on OpenJPA and OpenEJB)

Hibernate Example targeting Java SE

Spring Example targeting Java SE

  • Example.java: Example startup main
  • LocalDaoFactory.java: project-specific IGenericDaoFactory implementation that accepts automatic SpringGenericDao implementations via Spring IoC.
  • ICustomerDao.java: IGenericDao subtype that maps to named queries and gets implemented automatically by SpringGenericDao. Note the use of @QueryParameters annotation to map method arguments to Query parameters.
  • Customer.java: Data model object example
  • Product.java: Data model object example
  • Order.java: Data model object example
  • ToStringVisitor.java: Visitor that exemplifies externalizing toString implementations for a Data model