Hades - Domain class and DAO development framework - synyx

helpflightInternet και Εφαρμογές Web

10 Νοε 2013 (πριν από 3 χρόνια και 9 μήνες)

168 εμφανίσεις

Copyright ©
ii
Table of Contents
Preface .................................................................................................................................. iii
1. Assumptions .............................................................................................................. iii
2. Technologies ............................................................................................................. iii
3. Project metadata ...................................................................................................... iii
1. Core concepts ..................................................................................................................... 1
1.1. Introduction .............................................................................................................. 1
1.2. Entities and DAOs .................................................................................................... 1
1.3. Auditability .............................................................................................................. 3
2. Sample application ............................................................................................................ 6
2.1. Introduction ............................................................................................................. 6
2.1.1. Configuration ................................................................................................ 6
2.2. Infrastructure .......................................................................................................... 6
2.3. Basic entities and DAOs .......................................................................................... 8
2.3.1. Users and roles ............................................................................................. 8
2.3.2. DAOs ........................................................................................................... 10
2.3.3. Configuration .............................................................................................. 10
2.3.4. Client code .................................................................................................. 10
2.4. Easing configuration - Spring namespaces ............................................................ 11
2.4.1. Auto configuration ...................................................................................... 11
2.4.2. Using filters ................................................................................................ 12
2.5. Query methods ...................................................................................................... 12
2.5.1. Query lookup strategies .............................................................................. 13
2.5.2. Query creation ............................................................................................ 13
2.5.3. Using JPA NamedQueries ........................................................................... 14
2.5.4. Using @Query ............................................................................................ 15
2.5.5. Using named parameters ........................................................................... 16
2.5.6. Special parameter handling ........................................................................ 16
2.5.7. Modifying queries ....................................................................................... 16
2.6. Auditable entities .................................................................................................. 17
2.7. Using abstract base classes ................................................................................... 19
2.8. Using vendor specific features .............................................................................. 19
2.9. Custom implementations ...................................................................................... 20
2.10. Custom implementations .................................................................................... 22
2.10.1. Adding behaviour to single DAOs ............................................................. 22
2.10.2. Adding custom behaviour to all DAOs ..................................................... 24
3. Eclipse plugin ................................................................................................................... 26
3.1. Installation ............................................................................................................. 26
3.2. Features ................................................................................................................. 26
A. Namespace reference ...................................................................................................... 28
A.1. The <dao-config /> element .............................................................................. 28
A.2. The <dao /> element ........................................................................................... 28
B. Frequently asked questions ............................................................................................. 29
Glossary ............................................................................................................................... 30
iii
Preface
1. Assumptions
As Hades makes heavy use of Spring and JPA we assume you have certain knowledge of how to
work with theses frameworks and specifications. Hades is implemented using some container
hooks of Spring, AOP features. Nevetheless you do not have to have deep insight in conainer
internals to use Hades although it would let you understand things more deeply.
2. Technologies
JPA
The Java Persistence API was invented in conjunction with EJB3 and serves as standard for per-
sisting objects in JavaSE and JavaEE environments. It abstracts differences of various available
OR Mappers like Hibernate and EclipseLink and guarantees interoperability as far as possible.
Although the version 1.0 has its shortcomings, JPA can be considered a future technology.
Spring
Spring is the defacto standard application framework for Java applications. Its consistent pro-
gramming model, easy configuration and wide support for all kinds of third party libraries
makes it the first class citizen of application frameworks.
Spring & JPA
Spring offers a lot of support for various technologies in data access area. It's main benefit
regarding JPA is the ease and power of configuration along with proper exception translation
into Spring's DataAccessException hierarchy.
3. Project metadata
• Version control - http://git.synyx.org/hades.git
• Bugtracker - http://hades.synyx.org
• Repository - http://repo2.maven.org/maven2/org/synyx/hades
• Snapshot repsitory - https://oss.sonatype.org/content/repositories/snapshots/org/synyx/
hades
1
Chapter 1. Core concepts
1.1. Introduction
Implementing a data access layer of an application has been cumbersome for quite a while.
To much boilerplate code had to be written. Domain classes were anemic and havent been
designed in a real object oriented or domain driven manner.
The last few years have brought a lot of evolution regarding those topics. JPA brought annota-
tion driven persistence into Java, Spring established as lightweight Java development frame-
work offering a lot of support especially in the area of data access.
Using both of these technologies makes developers life a lot easier regarding rich domain
model's persistence. Nevertheless the amount of boilerplate code especially for DAOs is still
quite high. Besides that there is no higher level concept supporting you designing persistent
domain classes. Hades is aiming to bridge that gap, providing sophisticated support for do-
main modeling and easing persistence.
The following chapters will introduce the core concepts and interfaces of Hades roughly sur-
rounding various steps of sophistication. All these step will bring significant benefit to your
application but will introduce certain restrictions. So it's up to you to choose.
1.2. Entities and DAOs
The central interface in Hades is GenericDao. It is typed with the entity class to manage as
well as the id type of the entity and provides some sophisticated functionality around CRUD
for the entity managed.
Core concepts
2
Example 1.1. GenericDao Interface
public interface GenericDao<T, PK extends Serializable> {
T save(T entity);

T saveAndFlush(T entity);
·
T readByPrimaryKey(PK primaryKey);

List<T> readAll();

Page<T> readAll(Pageable pageable);

Long count();

void delete(T entity);

void flush();

boolean exists(PK primaryKey);

//  more functionality omitted.
}

Saves the given entity.
·
Saves the given entity and immediately flushes changes to the database.

Returns the entity identified by the given id.

Returns all entities.

Returns a page of entities.

Returns the number of entities.

Deletes the given entity.

Flushes pending changes to the database.

Returns whether an entity with the given id exists.
Hades provides a GenericDaoFactoryBean that allows setting up instances for this interface
in declarative manner. So all you need to do is declaring an interface extending and thus typing
the generic interface accordingly. To create DAO instances programatically Hades provides
GenericDaoFactory. Read more on configuration in Section 2.3.3, “Configuration”.
For more sophisticated DAO operations Hades provides ExtendedGenericDao. It contains
functionality that can not be implemented with standard JPA features in the version 1.0. So
implementations will have to rely on persistence providers proprietary API. Extending this
interface with your concrete DAO interface will require to use either Hibernate or EclipseLink.
Core concepts
3
Example 1.2. ExtendedGenericDao interface
public interface ExtendedGenericDao<T,
PK extends Serializable> extends GenericDao<T, PK> {
List<T> readByExample(T... examples); 
List<T> readbyExample(Sort sort, T... examples); ·
Page<T> readByExample(Pageable pageable, T... examples); 
Page<T> readByExample(Pageable pageable, Sort sort, T... examples); 
}

Returns all entities matching the given examples. If you provide more that one example,
their restrictions will be OR concatenated.

Returns all entities matching the given examples, sorted by the given sort option.

Returns a single page of the restriction result defined by the given example.

Returns a single page of the restriction result defined by the given example sorted by
the given sort option.
1.3. Auditability
Note
As of version 1.6 auditing through the usage of AuditingAdvice is deprecated. The
approach suffered various drawbacks such as the need to call GenericDao.save()
explicitly to trigger auditing. Additionally auditing only worked for the root entity
handed to the save() method. The new approach documented here solves all these
issues so we highly recommend to switch to use the new approach.
Most applications will require some auditability for entities allowing to track creation date
and user and modification date and user. Hades provides facilities to add this audition infor-
mation to entity transparently by AOP means. To take part in this functionality your domain
classes have to implement a more advanced interface:
Core concepts
4
Example 1.3. Auditable interface
public interface Auditable<U extends Persistable<PK>, PK extends Serializable>
extends Persistable<PK> {
U getCreatedBy();
void setCreatedBy(U createdBy);
DateTime getCreatedDate();
void setCreated(Date creationDate);
U getLastModifiedBy();
void setLastModifiedBy(U lastModifiedBy);
DateTime getLastModifiedDate();
void setLastModified(Date lastModifiedDate);
}
As you can see the modifying entity itself only has to be an entity. Mostly this will be some
sort of User entity, so we chose U as parameter type.
Note
To minimize boilerplate code Hades offers AbstractPersistable and AbstractAu-
ditable base classes that implement and preconfigure entities. Thus you can decide
to only implement the interface or enjoy more sophisticated support by extending the
base class.
General auditing configuration
Hades ships with an entity listener that can be used to trigger capturing auditing information.
So first you have to register the AuditingEntityListener inside your orm.xml to be used
for all entities in your persistence contexts:
Example 1.4. Auditing configuration orm.xml
<persistence-unit-metadata>
<persistence-unit-defaults>
<entity-listeners>
<entity-listener class=".hades.domain.auditing.support.AuditingEntityListener" />
</entity-listeners>
</persistence-unit-defaults>
</persistence-unit-metadata>
Now activating auditing functionlity is just a matter of adding the Hades auditing namespace
element to your configuration:
Example 1.5. Activating auditing in the Spring configuration
<hades:auditing auditor-aware-ref="yourAuditorAwareBean" />
Core concepts
5
As you can see you have to provide a bean that implements the AuditorAware interface which
looks as follows:
Example 1.6. AuditorAware interface
public interface AuditorAware<T, PK extends Serializable> {
T getCurrentAuditor();
}
Usually you will have some kind of authentication component in your application that tracks
the user currently working with the system. This component should be AuditorAware and
thus allow seemless tracking of the auditor.
6
Chapter 2. Sample application
2.1. Introduction
In order to introduce you to working with Hades we will develop a small sample application
managing users. As Hades is focussing on development of domain classes and persistence
it will not be a full fledged application but rather concentrate on that particular part of an
application built around the demo app.
We will start by assuming that only want to have basic Hades support stepping forward using
more sophisticated features of it.
2.1.1. Configuration
To get started with Hades you need to setup your application in the standard Spring man-
ner. The following examples leverage XML configuration style of the container but you
could easily use other approaches as well. We will separate configuration into two files.
infrastructure.xml contains a the basic infrastructure setup descibed in the next chapter.
This one will be used over the various sophistication levels of Hades. Beyond that we will cre-
ate certain further config files that contain configuration for various sophistication levels.
2.2. Infrastructure
DataSource
As you might already know, Spring's data base access support is mainly centered around
working with a DataSource implementation. Although you should rely on more sophisticat-
ed DataSource implementations like Commons DBCP, Spring comes with DriverManager-
DataSource out of the box that should be satisfying for testing purposes.
Note
Environment specific configuration that highly varies between deployments should
not be hardcoded into a Spring configuration file. Preferably, use a PropertyPlace-
holderConfigurer
1
to externalize those kinds of settings into an external properties
file that can easily customized by application administrators.
So we setup an instance of it in typical Spring Dependency Injection manner.
1
For more information see Spring's reference documentation [http://static.springframework.org/spring/docs/2.5.x/refer-
ence/beans.html#beans-factory-placeholderconfigurer] on that topic
Sample application
7
Example 2.1. DataSource configuration
<bean id="dataSource"
class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="com.mysql.jdbc.Driver"/> 
<property name="url" value="jdbc:mysql://localhost:3306/hades" /> ·
<property name="username" value="username" /> 
<property name="password" value="password" /> 
</bean>

Configure your database vendor's specific driver class
·
Point the data source to your database's location
 
Authentication credentials
EntityManager(Factory)
Example 2.2. EntityManager configuration
<bean id="entityManagerFactory"
class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="dataSource" ref="dataSource" /> 
<property name="jpaVendorAdapter"> ·
<bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
<property name="showSql" value="true" />
<property name="generateDdl" value="true" />
<property name="database" value="MYSQL" />
</bean>
</property>
</bean>

Reference the DataSource declared before
·
Apply a vendor specific adapter to add further configuration. In this case we use Hiber-
nate and tell it to use MySQL dialect for accessing the database, generate the required
database tables as needed and log SQL queries fired to the database
As you can see we have configured an EntityManagerFactoryBean to work with Hibernate
in our case. As Hades supports any JPA provider, we do not declare mandatory dependencies in
our pom.xml. Thus, you'll have to add the persistence provider of your choice to your project.
In our case this would look something like this:
Example 2.3. Hibernate dependency
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-entitymanager</artifactId>
<version>3.3.2-GA</version>
</dependency>
Note
You might have to add other dependencies as well (SLF4J in case of Hibernate). So
check the documentation of your persistence provider for setup details.
Sample application
8
Transaction management
Spring leverages consistent transaction abstraction through its PlatformTransactionMan-
ager interface and provides a JpaTransactionManager implementation out of the box.
Example 2.4. Transaction manager configuration
<bean id="transactionManager"
class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="entityManagerFactory" />
</bean>
BeanPostProcessors
As Hades leverages Spring 2.5 annotations to activate exception translation and injecting
EntityManager instances we need to configure 2 BeanPostProcessors.
Example 2.5. BeanPostProcessor configuration
<bean
class="org...PersistenceAnnotationBeanPostProcessor" />
<bean
class="org...PersistenceExceptionTranslationPostProcessor" />
2.3. Basic entities and DAOs
Now we are going to create the entities and DAOs needed to manage users with roles. Note
that we will start with an implementation with the least possible coupling to Hades. The
will force us to configure a few things ourselves but decrease dependencies. If you want to
know, how you can ease things a little more see Section 2.7, “Using abstract base classes” and
Section 2.4, “Easing configuration - Spring namespaces”.
2.3.1. Users and roles
As we want to create a small user management application, the primary entities we will deal
with are User and Role. Take a look at the code snippets:
Sample application
9
Example 2.6. User entity
@Entity
public class User {
public static final long serialVersionUID = 123L
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
private String username;
private String password;
private String emailAddress;
@ManyToMany
private Set<Role> roles;
public Long getId() {
return this.id;
}
// Further getters and setters omitted
public boolean isNew() {
return null == this.id;
}
}
Note that we decide to have an id type of Long. We have to add annotations for the id ourselves
and implement isNew() manually, too. We create a many-to-many relationship to the Role
class and store some string values like username, password and email address.
Example 2.7. Role entity
@Entity
public class Role {
private static final long serialVersionUID = -123L;
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Integer id;
private String name;
public Integer getId() {
return this.id;
}
// Further getters and setters omitted
public boolean isNew() {
return null == this.id;
}
}
The Role class looks quite similar. Note that we decide for an alternate id type. So mixing id
type is no problem at all.
Sample application
10
2.3.2. DAOs
As we have modeled the entities we need to add an interface for a DAO handling persistence
operations for them:
Example 2.8. UserDao and RoleDao interface
public interface UserDao extends GenericDao<User, Long> {
}
public interface RoleDao extends GenericDao<Role, Integer> {
}
As you can see the interfaces serve typing purposes only for now. We will add further func-
tionality to them later. GenericDao provides most of the required persistence operations.
Hades provides various implementations of this interface so that you don't need to code one
on your own.
2.3.3. Configuration
GenericJpaDao is the base implementation of GenericDao that serves basic purposes very
well. It uses Spring's exception translation and entity manager injection facilities so that its
creation logic is encapsulated into GenericDaoFactoryBean. So the basic configuration for
a DAO instance looks as follows:
Example 2.9. Simple DAO configuration
<import resource="infrastructure.xml" /> 
<bean id="userDao"
class="org.synyx.hades.dao.orm.GenericDaoFactoryBean">
<property name="daoInterface" value="org.synyx.hades.dao.UserDao" />
</bean> ·
<bean id="roleDao"
class="org.synyx.hades.dao.orm.GenericDaoFactoryBean">
<property name="daoInterface" value="org.synyx.hades.dao.RoleDao" />
</bean>

Import infrastructure configuration. Supposed we have combined the configuration ex-
amples shown in Section 2.2, “Infrastructure” into a file named infrastructure.xml
·
Declare the DAO interface you want to expose. This interface has to extend GenericDao.
This is smallest standard XML configuration possible. There are a lot more options on Gener-
icDaoFactoryBean, but you rather choose XML namespace configuration due to less verbosi-
ty.
2.3.4. Client code
The previously declared UserDao can be accessed via its bean id from the ApplicationCon-
text, although you definately are better off letting the container inject it into you client:
Sample application
11
Example 2.10. Manual lookup of UserDao
ApplicationContext ctx = new ClasspathXmlApplicationContext(
"applicationContext.xml");
UserDao userDao = (UserDao) ctx.getBean("userDao");
User user = userDao.readByPrimaryKey(1L);
2.4. Easing configuration - Spring namespaces
Configuring DAOs the standard way can become cumbersome if your application requires a
lot of DAOs. With help of Spring 2.5 namespaces there is a more sophisticated way to config-
ure them.
Example 2.11. DAO configuration with Spring namespaces
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:hades="http://schemas.synyx.org/hades" 
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
http://schemas.synyx.org/hades ·
http://schemas.synyx.org/hades/hades.xsd">
<import resource="infrastructure.xml" /> 
<hades:dao-config base-package="org.synyx.hades.dao"> 
<hades:dao id="userDao" /> 
<hades:dao id="roleDao" />
</hades:dao-config>
</beans>
 ·
Import the dao namespace to be available in the xml configuraton document.

Import infrastructure configuration.

Declare base packages to construct domain classes and DAO interfaces.

Declare a single DAO instance. Each <dao /> element will result in a single declara-
tion of a GenericDaoFactoryBean with a DAO interface set to ${dao-config.base-
package}.${dao.id}. Given this example this will result in a DAO interface of
org.synyx.hades.dao.UserDao registered under userDao.
This configuration replaces simple configuration mechanism entirely so we encourage to use
this kind of configuration over the simple one.
The <dao-config /> element allows two further attributes to be defined. With dao-name-
postfix you can customize the bean id for the DAO registered. This defaults to Dao.
2.4.1. Auto configuration
You can simplify configuration even more by adding no <dao /> elements to <dao-config /
> at all.
Sample application
12
Example 2.12. Automatic DAO configuration
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:hades="http://schemas.synyx.org/hades"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
http://schemas.synyx.org/hades
http://schemas.synyx.org/hades/hades.xsd">
<import resource="infrastructure.xml" />
<hades:dao-config base-package="org.synyx.hades.dao" />
</beans>
This will trigger auto detection mechanism of DAOs that extend GenericDao or Extended-
GenericDao. For each candidate found it will set up an DAO instances supposing you've placed
the DAO interfaces in the configured package and named them as described above.
Note
In case you need to wire an EntityManagerFactory to a DAO instance or all DAO
instances explicitly use entity-manager-factory-ref attribute to point to the de-
sired Spring bean.
2.4.2. Using filters
By default Hades will pick up every interface extending GenericDao located underneath the
configured base package and create a bean instance for it. However, you might want to gain
finer grained control over which interfaces bean instances get created for. Hades supports
the use of <include-filter /> and <exclude-filter /> elements inside <dao-config /
>. The samantics are exactly equivalent to the elements in Spring's context namespace. For
details see Spring reference documentation [http://static.springsource.org/spring/docs/2.5.x/
reference/beans.html#beans-scanning-filters] on these elements.
E.g. to exclude certain interfaces from instantiation as Hades DAO, you could use the follow-
ing configuration:
Example 2.13. Using exclude-filter element
<hades:dao-config base-package="org.synyx.hades.dao">
<exclude-filter type="regex" expression=".*SomeDao" />
</hades:dao-config>
This would exclude all interface ending on SomeDao from being instantiated.
2.5. Query methods
Next to standard CRUD functionality GenericJpaDao allows sophisticated execution of
queries by declaring methods in the DAO interface. Let's see how configuration of a query to
lookup users by their email address can be realized.
Sample application
13
2.5.1. Query lookup strategies
Queries can be executed with 3 different strategies. These strategies define how the JPA query
is constructed at runtime. These strategies can either be configured at the GenericDaoFac-
toryBean directly or used via XML namespace configuration.
CREATE
This strategy will try to construct a JPA query from the query method's name. Thus you don't
need to declare a named query explicitly. This is quite useful if the queries are simple and no
special JPA QL is required. CREATE strategy ties your mehod names to the query, what might
be unwanted. Read more about query construction in Section 2.5.2, “Query creation”.
USE_DECLARED_QUERY
This strategy tries to find a declared query that can either be defined using JPA @NamedQuery
means or Hades @Query annotation (see Section 2.5.3, “Using JPA NamedQueries” and Sec-
tion 2.5.4, “Using @Query” for details). If no declared query is found execution of the query
will fail.
CREATE_IF_NOT_FOUND (default)
This strategy is actually a combination of the both mentioned above. It will try to lookup a
declared query first but create a custom method name based query if no named query was
found. This is default lookup strategy and thus will be used if you don't configure anything
explicitly. It allows quick query definition by method names but also custom tuning of these
queries by introducing declared queries for those who need explicit tuning.
2.5.2. Query creation
The hades query builder mechanism is useful to build basic WHERE clauses queries. Hades will
directly translate the method name into a where clause. Basically you can define conditions
on direct entity properties and concatenate them with AND and OR.
Example 2.14. Query creation from method names
public interface UserDao extends GenericDao<User, Long> {
findByEmailAddressAndLastname(String emailAddress, String lastname);
}
This method will result in the following query:
from User u where u.emailAddress = ?1 and u.lastname = ?2
Hades will check the query against the domain class to validate the properties exist. So you
either have a property of the appropriate name or a getter method. Furthermore Hades will
strip a list of prefixes from the method name before translating it into a query. The prefixes
are: findBy, find, readBy, read, getBy as well as get. Besides AND you can use OR to concate-
nate property constraints. Note, that due to the lack of parenthesis natural binding order (AND
binds more than OR) is used for the query.
Sample application
14
Table 2.1. Supported keywords inside method names
Keyword
Sample
JPQL snippet
And
findByLastnameAnd-
Firstname
 where x.lastname = ?1 and
x.firstname = ?2
Or
findByLastnameOrFirst-
name
 where x.lastname = ?1 or x.firstname
= ?2
Between
findByStartDateBetween
 where x.startDate between 1? and ?2
LessThan
findByAgeLessThan
 where x.age < ?1
GreaterThan
findByAgeGreaterThan
 where x.age > ?1
IsNull
findByAgeIsNull
 where x.age is null
IsNotNull,NotNull
findByAge(Is)NotNull
 where x.age not null
Like
findByFirstnameLike
 where x.firstname like ?1
NotLike
findByFirstnameNotLike
 where x.firstname not like ?1
OrderBy
findByAgeOrderByLast-
nameDesc
 where x.age > ?1 order by x.lastname
desc
Not
findByLastnameNot
 where x.lastname <> ?1
2.5.3. Using JPA NamedQueries
Note
The examples use simple <named-query /> element and @NamedQuery annotation.
The queries for these configuration elements have to be defined in JPA query language.
Of course you can use <named-native-query /> or @NamedNativeQuery, too. These
elements allow you to define the query in native SQL by losing the database platform
independence.
XML named query definition
To use XML configuration simply add the necessary <named-query /> element to the
orm.xml JPA configuration file located in META-INF folder of your classpath. Automatic in-
vocation of named queries is enabled by using some defined naming convention. For more
details see below.
Example 2.15. XML named query configuration
<named-query name="User.findByLastname">
<query>FROM User u WHERE u.lastname = ?1</query>
</named-query>
As you can see the query has a special name, the GenericJpaDao uses to resolve it at runtime.
Sample application
15
Annotation configuration
Annotation configuration has the advantage not to need another config file to be edited,
probably lowering maintenance cost. You pay for that benefit by the need to recompile your
domain class for every new query declaration.
Example 2.16. Annotation based named query configuration
@Entity
@NamedQuery(name = "User.findByEmailAddress",
query = "FROM User u WHERE u.emailAddress = ?1")
public class User {
}
Declaring interfaces
To allow execution of this named query all you need to do is to specify the UserDao as follows:
Example 2.17. Query method declaration in UserDao
public interface UserDao extends GenericDao<User, Long> {
List<User> findByLastname(String lastname);
User findByEmailAddress(String emailAddress);
}
Declaring this method GenericJpaDao will try to resolve a call to this method to a named
query starting with the simple name of the configured domain class followed by the method
name separated by a dot. Note, that Hades distinguishes between query methods for a single
object or lists of object. It will try to retrieve a single result if you provide a return value
assignable from the configured domain class. Otherwise i will try to call a named query to
return a list. Be sure your named query for a single instance truely returns only one instance.
2.5.4. Using @Query
Using named queries to declare queries for entities is a valid approach and works fine for
a small number amount of queries. As the queries themselves are tied to a Java method to
execute them you actually can bind them to the query executing methods using Hades @Query
annotation rather than annotating them to the domain class. This will free the domain class
from persistence specific information and colocate the query to the DAO interface.
Querys annotated to the query method will trump queries defined using @NamedQuery or
named queries declared in in orm.xml.
Example 2.18. Declare query at the query method using @Query
public interface UserDao extends GenericDao<User, Long> {
@Query("FROM User u WHERE u.emailAddress = ?1")
User findByEmailAddress(String emailAddress);
}
Sample application
16
2.5.5. Using named parameters
By default Hades will use position based parameter binding as described in all the samples
above. This makes query methods a little error prone to refactorings regarding the parameter
position. To solve this issue you can use @Param annotation to give a method parameter a
cncrete name and bind the name in the query:
Example 2.19. Using named parameters
public interface UserDao extends GenericDao<User, Long> {
@Query("FROM User u WHERE u.firstname = :firstname or u.lastname = :lastname")
User findByLastnameOrFirstname(@Param("lastname") String lastname
@Param("firstname") String firstname;
}
Note that the method parameters are switched according to the occurrence in the query
defined.
2.5.6. Special parameter handling
To hand parameters to your query you simply define method parameters as already seen
in in examples above. Besides that Hades recognizes certain Hades specific types to apply
pagination and sorting to your queries dynamically.
Example 2.20. Using Pageable and Sort in query methods
Page<User> findByLastname(String lastname, Pageable pageable);
List<User> findByLastname(String lastname, Sort sort);
List<User> findByLastname(String lastname, Pageable pageable);
The first method allows you to pass a Pageable instance to the query method to dynamically
add paging to your statically defined query. Sorting options are handed via the Pageable in-
stance, too. If you only need sorting, simply add a Sort parameter to your method. As you also
can see, simply returning a List is possible, too. Hades will then not retrieve the additional
metadata required to build the actual Page instance but rather simply restrict the query to
lookup only the given rante of entities.
2.5.7. Modifying queries
All the sections before described how to declare queries to access a given entity or collection
of entitites. Of course you can add custom modifying behaviour by using facilities described
in Section 2.9, “Custom implementations”. As this approach is feasible for comprehensive
custom functionality, you can achieve the execution of modifying queries that actually only
need parameter binding by annotating the query method with @Modifying:
Example 2.21. Declaring manipulating queries
@Modifying
@Query("update User u set u.firstname = ?1 where u.lastname = ?2")
Long setFixedFirstnameFor(String firstname, String lastname);
Sample application
17
This will trigger the query annotated to the method as updating query instead of a selecting
one.
2.6. Auditable entities
Suppose you want to keep track of who created user entities and who changed them. All you
need to do is implement Auditable interface
Example 2.22. AuditableUser
@Entity
public class AuditableUser implements Auditable<User, Long> {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
private User createdUser;
private Date createdDate;
private User modifiedUser;
private Date modifiedDate;
// Getters and setters according to Auditable and
// Persistable omitted
}
Suppose you have the following three configuration files infrastructure.xml (for in-
frastructure setup), audition-context.xml (to setup the audition advice) and dao-
context.xml (for the actual DAOs) the work of the AuditingAdvice can be demonstrated
by the following testcase:
Sample application
18
Example 2.23. Testcase for AuditingAdvice
@RunWith(SpringJUnit4ClassRunner.class) 
@ContextConfiguration(location = { "infrastructure.xml",
"audition-context.xml", "dao-context.xml" })
@Transactional
public class AuditionAdviceTest extends AbstractJpaTests {
@Autowired
private UserDao userDao; ·
@Autowired
private AuditionAdvice advice;
private AuditableUser user; 

@Before
public void setUp() {
user = new AuditableUser();
user.setUsername("username");
user.setPassword("password");
user.setEmailAddress("foo@bar.com");
AuditorAware auditorAware = Mockito.mock( 
AuditorAware.class);
Mockito.when(auditorAware.getCurrentUser())
.thenReturn(user);
advice.setAuditorAware();
}
@Test
public void testApplicationOfAuditionAdvice() {
user = userDao.save(user);
assertEquals(user, user.getCreatedBy());
assertNotNull(user.getCreationDate());
assertEquals(user, user.getLastModifiedBy());
assertNotNull(user.getLastModifiedDate()); 
}
}

Configure the test class to be dependency injected and transactional.
·
References to Spring beans.

Test user to be inserted into the database.

Create a dummy User instance and a mock CurrentUserAware, that always returns the
dummy user. Apply this mock to the advice.

The actual test simply saves the dummy User instance and verifys the advice got applied.
Note that advice application is completely transparent to the client.
Sample application
19
2.7. Using abstract base classes
Using Hades you can implement data acces for plain JPA entities as you like. So these entity
classes usually share a common basic setup, e.g. an id property with an @Id annotation and
an id-generation strategy applied. So Hades provides a simple base class you can inherit with
your entities from and thus free it from the noise of these rather technical properties.
Using AbstractPersistable would simplify User code like this
Example 2.24. User based on AbstractPersistable
@Entity
public class User extends AbstractPersistable<Long> {
public static final long = 123L;
private String username;
private String password;
private String emailAddress;
@ManyToMany
private Set<Role> roles;
// Further getters and setters omitted
}
Note that almost technical artefacts are gone.
If you are using auditable entities AbstractAuditable is your base class of choice. This will
save you from writing getters and setters for 4 class members
Example 2.25. AuditableUser based on AbstractAuditable
@Entity
public class AuditableUser extends AbstractAuditable<User, Long> {
public static final long = 123L;s
private String username;
private String password;
private String emailAddress;
@ManyToMany
private Set<Role> roles;
}
2.8. Using vendor specific features
All the functionality described until now can be used with any JPA persistence provider as it
only relies on features specified by JPA. Nevertheless JPA does not include certain features
like the well known criteria API. As some persistence providers provide more sophisticated
features we introduce the ExtendedGenericDao interface and a few implementations that
make use of proprietary persistence provider's features. Thus it is your choice to use the stan-
Sample application
20
dard JPA based GenericJpaDao and restrict yourself on features defined in the JPA spec or
rely on your persistence providers extended features.
Currently Hades provides implementations for ExtendedGenericDao based on Hibernate and
EclipseLink. Note, that you can use basic DAO functionality with any JPA persistence provider.
Note
Starting with version 0.4 Hades is able to detect the persistence provider you chose
itself. So there is no need to configure it explicitly. It will be able to use the appropriate
types to back the DAO proxy itself if you use either Hibernate or EclipseLink. For any
other persistence provider it will fall back on GenericJpaDao, that does not provide
the extended DAO functionality listed in ExtendedGenericDao. If you try to create
DAO instances for DAO interfaces extending ExtendedGenericDao but use OpenJPA
e.g. Hades will complain at configuration time.
E.g. to setup your application to use the GenericHibernateJpaDao you have to extend the
DAO configuration as follows.
Example 2.26. Configuration to use GenericHibernateJpaDao
<dao-config base-package="org.synyx.hades.dao">
<dao name="userDao" />
<dao name="roleDao" />
</dao-config>

Declare the specific DAO implementation in the <dao-config /> element. This imple-
mentaion class has to implement at least GenericDao but of course only makes sense if
the interface your specific DAO interface extends is also implemented by the class.
Note
Using EclipseLink as a persistence provider you will have to activate load time weaving
for your application. Furthermore there is a known bug [https://bugs.eclipse.org/bugs/
show_bug.cgi?id=240618] regarding combination of EclipseLink and HSQL you should
be aware of. With EclipseLinkHSQLPLatform Hades provides a workaround for this.
See the eclipselink.xml configuration file in the test directory for details.
2.9. Custom implementations
Often it is necessary to provide a custom implementation for a few DAO methods. Hades eases
custom DAO functionality development a lot and allows easy integration with hades generic
DAO and query method functionality. To enrich a generic DAO with custom functionality you
have to define an interface and an implementation for that functionality first and let the DAO
interface you provide by now extend that custom interface.
Example 2.27. Interface for custom DAO functionality
public interface UserDaoCustom {
public void someCustomMethod(User user);
}
Sample application
21
Example 2.28. Implementation of custom DAO functionality
public class UserDaoImpl implements UserDaoCustom {
public void someCustomMethod(User user) {
// Your custom implementation
}
}
Note that the implementation itself does not depend on Hades and can be a regular Spring
bean. So you can either use standard dependency injection behaviour to inject references to
other beans, take part in aspects and so on.
Example 2.29. Changes to the standard DAO interface
public interface UserDao extends GenericDao<User, Long>, UserDaoCustom {
// Declare query methods here
}
Let your standard DAO interface extend the custom one. This makes generic DAO and custom
functionality available to clients.
Configuration
If you use namespace configuration Hades tries to autodetect custom implementations by
looking up classes in the configured dao package using the naming conventions for the DAO
interface but appending the property dao-impl-postfix to the classname. This prefix de-
faults to DaoImpl.
Example 2.30. Configuration example
<dao-config base-package="foo.bar.dao">
<dao id="userDao" />
</dao-config>
<dao-config base-package="foo.bar.dao" dao-impl-postfix="FooBar">
<dao id="userDao" />
</dao-config>
The first configuration example will try to lookup a class foo.bar.dao.UserDaoImpl
to act as custom DAO implementation, where the second example will try to lookup
foo.bar.dao.UserDaoFooBar.
Manual wiring
The approach above works perfectly well if your custom implementation uses annotation
based configuration and autowring entirely as will be trated as any other Spring bean. If your
customly implemented bean needs some special wiring you simply declare the bean and name
it after the conventions just descibed. Hades will the pick up the custom bean by name rather
than creating an own instance.
Sample application
22
Example 2.31. Manual wiring of custom implementations (I)
<dao-config base-package="foo.bar.dao">
<dao id="userDao" />
</dao-config>
<bean id="userDaoImpl" class="...">
<!-- further configuration -->
</bean>
This also works if you use automatic DAO lookup without defining single <dao /> elements.
In case you are not in control of the implementation bean name (e.g. if you wrap a generic dao
facade around an existing DAO implementation) you can explicitly tell the <dao /> element
which bean to use as custom implementation by using the dao-impl-ref attribute.
Example 2.32. Manual wiring of custom implementations (II)
<dao-config base-package="foo.bar.dao">
<dao id="userDao" dao-impl-ref="customDaoImplementation" />
</dao-config>
<bean id="customDaoImplementation" class="...">
<!-- further configuration -->
</bean>
2.10. Custom implementations
2.10.1. Adding behaviour to single DAOs
Often it is necessary to provide a custom implementation for a few DAO methods. Hades eases
custom DAO functionality development a lot and allows easy integration with hades generic
DAO and query method functionality. To enrich a generic DAO with custom functionality you
have to define an interface and an implementation for that functionality first and let the DAO
interface you provide by now extend that custom interface.
Example 2.33. Interface for custom DAO functionality
public interface UserDaoCustom {
public void someCustomMethod(User user);
}
Sample application
23
Example 2.34. Implementation of custom DAO functionality
public class UserDaoImpl implements UserDaoCustom {
public void someCustomMethod(User user) {
// Your custom implementation
}
}
Note that the implementation itself does not depend on Hades and can be a regular Spring
bean. So you can either use standard dependency injection behaviour to inject references to
other beans, take part in aspects and so on.
Example 2.35. Changes to the standard DAO interface
public interface UserDao extends GenericDao<User, Long>, UserDaoCustom {
// Declare query methods here
}
Let your standard DAO interface extend the custom one. This makes generic DAO and custom
functionality available to clients.
Configuration
If you use namespace configuration Hades tries to autodetect custom implementations by
looking up classes in the configured dao package using the naming conventions for the DAO
interface but appending the property dao-impl-postfix to the classname. This prefix de-
faults to DaoImpl.
Example 2.36. Configuration example
<dao-config base-package="foo.bar.dao">
<dao id="userDao" />
</dao-config>
<dao-config base-package="foo.bar.dao" dao-impl-postfix="FooBar">
<dao id="userDao" />
</dao-config>
The first configuration example will try to lookup a class foo.bar.dao.UserDaoImpl
to act as custom DAO implementation, where the second example will try to lookup
foo.bar.dao.UserDaoFooBar.
Manual wiring
The approach above works perfectly well if your custom implementation uses annotation
based configuration and autowring entirely as will be trated as any other Spring bean. If your
customly implemented bean needs some special wiring you simply declare the bean and name
it after the conventions just descibed. Hades will the pick up the custom bean by name rather
than creating an own instance.
Sample application
24
Example 2.37. Manual wiring of custom implementations (I)
<dao-config base-package="foo.bar.dao">
<dao id="userDao" />
</dao-config>
<bean id="userDaoImpl" class="">
<!-- further configuration -->
</bean>
This also works if you use automatic DAO lookup without defining single <dao /> elements.
In case you are not in control of the implementation bean name (e.g. if you wrap a generic dao
facade around an existing DAO implementation) you can explicitly tell the <dao /> element
which bean to use as custom implementation by using the dao-impl-ref attribute.
Example 2.38. Manual wiring of custom implementations (II)
<dao-config base-package="foo.bar.dao">
<dao id="userDao" dao-impl-ref="customDaoImplementation" />
</dao-config>
<bean id="customDaoImplementation" class="">
<!-- further configuration -->
</bean>
2.10.2. Adding custom behaviour to all DAOs
In other cases you might want to add a single method to all of your DAOs. So the approach
just shown is not feasible. The first step to achieve this is adding and intermediate interface
to declare the shared behaviour
Example 2.39. An interface declaring custom shared behaviour
public interface MyGenericDao<T, PK extends Serializable>
extends GenericDao<T, PK> {
void sharedCustomMethod(PK id);
}
Now your individual DAO interfaces will extend this intermediate interface to include the
functionality declared. The second step is to create an implementation of this interface that
extends GenericJpaDao and will act as custom base class for the DAO proxies then.
Note
If you're using automatic DAO interface detection using the Spring namespace using
the interface just as is will cause Spring trying to create an instance of MyGeneric-
Dao. This is of course not desired as it just acts as indermediate between GenericDao
and the actual DAO interfaces you want to define for each entity. To exclude an in-
terface extending GenericDao from being instantiated as DAO instance annotate it
with @NoDaoBean.
Sample application
25
Example 2.40. Custom DAO base class
public class MyGenericDaoImpl<T, PK extends Serializable>
extends GenericJpaDao<T, PK> implements MyGenericDao<T, PK> {
public void sharedCustomMethod(PK id) {
// implementation goes here
}
}
In the general case you will extend GenericJpaDao. In case you rely on behaviour provided
by special JPA providers you might want to extend the appropriate base class (e.g. Gener-
icHibernateJpaDao). So you can simply instantiate MyGenericDaoImpl. The last step to get
this implementation used as base class for Hades DAOs is replacing the standard Generic-
DaoFactoryBean with a custom one overriding getDaoClass() returning your custom im-
plementation.
Example 2.41. Custom DAO factory bean
public class MyGenericDaoFactory<T extends GenericDao<?, ?>
extends GenericDaoFactoryBean<T> {
protected Class<? extends GenericJpaDao> getDaoClass() {
return MyGenericDaoImpl.class;
}
}
Finally you can either declare beans of the custom factory directly or use the factory-class
attribute of the Spring namespace to tell Hades to use your custom factory implementation.
Example 2.42. Using the custom factory with the namespace
<dao-config base-package="foo.bar.dao"
factory-class="com.acme.MyGenericDaoFactory" />
26
Chapter 3. Eclipse plugin
To tightly integrate Hades into your application it is useful to leverage the features provided by Spring
IDE. You can achieve this using the Hades Eclipse plugin. This chapter explains in detail how to install
the plugin and what features you can expect by it.
3.1. Installation
You can install the plugin by simply pointing your Eclipse update manager to http://
updatesite.synyx.org and choosing the Hades Namespace Integration.
3.2. Features
Code completion for XML elements attributes
By handing over the Hades XSD you gain code completion for XML elements and especially at-
tributes. This regards base-package in particular as well as the custom-element-ref attribute
in the <dao /> element.
Beans detection using automatic dao detection mode
If you use the automatic DAO detection mode as shown in Figure 3.1, “Hades integration
into Spring IDE” you will get all discovered DAO beans correctly listed in the Spring Elements
section of your Project Explorer. The beans also lists property values like the query lookup
strategy including implicit defaults.
Marking the DAO interfaces to be Spring beans
The DAO interfaces Hades creates beans for are marked with the usual Spring Bean S you are
used to from other bean classes.
Content assist for bean references is aware of Hades beans
Trying to reference a DAO bean will now correctly show up the beans as suggestions during
content assist.
Eclipse plugin
27
Figure 3.1. Hades integration into Spring IDE
28
Appendix A. Namespace reference
A.1. The <dao-config /> element
The <dao-config /> element acts as container for <dao /> elements or can be left empty
to trigger auto detection
1
of DAO instances. Attributes defined for <dao-config /> act are
propagated to contained <dao /> elements but can be overridden of course.
Table A.1. Attributes
Name
Description
base-package
Defines the package to be used to construct DAO inteface
names from or to be scanned for DAO interfaces extending
GenericDao in auto detection mode. All packages below the
configured package will be scanned, too. In auto configura-
tion mode (no nested <dao /> elements) wildcards are also
allowed.
dao-impl-postfix
Defines the postfix to autodetect custom DAO implementa-
tions. Classes whose names end with the configured postfix
will be considered as candidates. Defaults to Impl.
query-lookup-strategy
Determines the strategy to be used to create finder queries.
See Section 2.5.1, “Query lookup strategies” for details. De-
faults to create-if-not-found.
entity-manager-factory-ref
Possibility to wire an EntityManagerFactory explicitly in
case multiple ones could be resolved.
A.2. The <dao /> element
The <dao /> element can contain all attributes of <dao-config /> except base-package.
This will result in overriding the values configured in the surrounding <dao-config /> block.
Thus here we will only document extended attributes.
Table A.2. Attributes
id
Defines the id of the bean the DAO instance will be regis-
tered under as well as the DAO interface name.
custom-impl-ref
Defines a reference to a custom DAO implementation bean.
1
see Section 2.4.1, “Auto configuration”
29
Appendix B. Frequently asked questions
B.1. Common
B.1.1.I'd like to get more detailled logging information on what methods are called inside
GenericDao, e.g. How can I gain them?
You can make use of CustomizableTraceInterceptor provided by Spring:
<bean id="customizableTraceInterceptor" class="
org.springframework.aop.interceptor.CustomizableTraceInterceptor">
<property name="enterMessage" value="Entering $[methodName]($[arguments])"/>
<property name="exitMessage" value="Leaving $[methodName](): $[returnValue]"/>
</bean>
<aop:config>
<aop:advisor advice-ref="customizableTraceInterceptor"
pointcut="execution(public * org.synyx.hades.dao.GenericDao+.*(..))"/>
</aop:config>
B.2. Infrastructure
B.2.1.Currently I have implemented a DAO layer based on HibernateDaoSupport. I create
a SessionFactory by using Springs AnnotationSessionFactoryBean. How do I get
Hades DAOs working in this environment.
You have to replace AnnotationSessionFactoryBean with the Local-
ContainerEntityManagerFactoryBean as described in the section called
“EntityManager(Factory)”. Supposed you have registered it under entityManager-
Factory you can reference it in you DAOs based on HibernateDaoSupport as follows:
Example B.1. Looking up a SessionFactory from an HibernateEntityManagerFactory
<bean class="com.acme.YourDaoBasedOnHibernateDaoSupport">
<property name="sessionFactory">
<bean factory-bean="entityManagerFactory"
factory-method="getSessionFactory" />
</property>
</bean>
B.3. Auditing
B.3.1.I want to use Hades auditing capabilities but have my database already set up to set
modification and creation date on entities. How to prevent Hades to set the date pro-
grammatically.
Just configure AuditingAdvice accordingly. The property you might want to look for
is dateTimeForNow.
30
Glossary
A
AOP Aspect oriented programming
C
Commons DBCP Commons DataBase Connection Pools - Library of the Apache foundation
offering pooling implementations of the DataSource interface.
CRUD Create, Read, Update, Delete - Basic persistence operations
D
DAO Data Access Object - Pattern to separate persisting logic from the object
to be persisted
Dependency Injection Pattern to hand a component's dependency to the component from out-
side, freeing the component to lookup the dependant itself. For more in-
formation see http://en.wikipedia.org/wiki/Dependency_Injection.
E
EclipseLink Object relational mapper implementing JPA - http://www.eclipselink.org
H
Hibernate Object relational mapper implementing JPA - http://www.hibernate.org
J
JPA Java Persistence Api
S
Spring Java application framework - http://www.springframework.org