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