Polyforms - Reduce DAO Code Duplication
The goal of the Polyforms project is to remove the heavily duplicated glue code to tie data access objects to the underlying persistence API. The approach used in the framework is to automatically implement service methods on a Repository interface defined by the developer. Methods defined on the interface are, by default, linked to database operations via naming conventions. For example, the wiki discusses how to implement a repository for a User entity object. First, the API for the repository must be defined:
public interface UserRepository extends EntityRepository<User, String> {
@Finder
List<User> findByCreator(User creator);
}
The @Finder annotation marks the method for Polyforms. Rather than creating an implementation for the UserRepostiory, however, a matching Hibernate query needs to be provided on the User entity via another annotation.
@NamedQueries({
@NamedQuery(name = "User.findByCreator", query = "select u from User u where u.creator = :creator"),
})
public class User {
...
}
As per the documentation, the convention used to find queries is based on the method name, as well as the name of the entity itself:
The rule for mapping method with Named Query is [name of Named Query] = [name of Entity].[name of method]. you can specify the name of Named Query in @Finder as @Finder("findUserByName"), then the name of Named Query will be "User.findUserByName".
In addition to the @Finder annotation, there is also an @Updater and a @Counter annotations to provide support for mass updates and counting queries respectively. The
EntityRepositoryparent interface already provides support for saving single entities, deleting, and retrieving by identifier.
All of this wiring is done via the
Spring frameworkand relies on Spring aspects to be able to provide runtime implementations of the APIs.
Other functionality supported by Polyforms includes:
- Automatic management of tracking information (created by, created date, modified by, modified date)
- Transparent pagination support
- Definition of transaction boundaries via annotation
- Domain event model to decouple persistence events from application functionality
More information is available on the
Polyforms wiki.
Huh?
by
Ilja Preuß
Re: Huh?
by
George G
I like the idea.
Add this to Spring framework
by
Vineet Bhatia
another annotation based DAO
by
Mert Can Akkan
www.altuure.com/2008/10/02/who-needs-implementa...
have fun
Re: Huh?
by
Tong Kuisong
Take a look at Hades project
by
Oliver Gierke
findByUsername on a UserDao for a User class would result in from User u where u.username = ?
Of course this is only suitable for very rudimentary queries but you can always override this with a namedquery.
Furthermore Hades seems to offer more sophisticated support like auditing and a Spring namespace to easy configuration.
trac.synyx.org/hades
Regards,
Ollie
Re: Take a look at Hades project
by
Mario Gleichmann
i just did some investigations on Hades over the weekend.
God job!
For all others, interested in that topic - i would definitely take a closer look!
Greetings
Mario
Re: Take a look at Hades project
by
Oliver Gierke
I'm not that overwhelming but appreciate your congratulations ;).
Regards,
Ollie
Re: Huh?
by
Ilja Preuß
Arid POJOs provides generic DAOs with dynamic finders for Hibernate
by
Chris Richardson
Chris
Re: Take a look at Hades project
by
Tong Kuisong
Re: Take a look at Hades project
by
Pete the Wheat
Re: Take a look at Hades project
by
Oliver Gierke
I agree, that you consider libraries in detail, especially if it touches the core of your application. But I guess you wouldn't blindly follow a "1.0" tag without testing it, would you? ;)
So feel free to play with it a little, push the boundries and don't hesitate to comment on things you don't like :).
@Kusiong
Yes, I've browsed through the project repository a litte. I especially like the idea to map DTOs against domain object automatically. We seem to have some overlaps but guess we can surely find other projects out there that implemented this idea. So keep up the good work!
Regards, Ollie
Similar things I have done
by
Shum Adrian
www-128.ibm.com/developerworks/java/library/j-g...
In my current project, we do adopted a similar framework, with a lot of things extra. In fact I am also planning to tidy it up and release a generic dao framework later if I have time.
Base on what I did, there are some comments on what u described here:
1) You gotta have annotation for input argument to 'map' it to the named parameter place holder. By reflection I think there is no way to get the input argument name
2) Base on our experience, putting the query as named query, is hard to debug if there is syntax error. We use Hibernate + Spring and result of incorrect named query is just a bunch of non-understandable errors. Therefore in my own framework, I provided @Query(query="your query") to annotate the finder method, and as the query is really executed in runtime, we get the understandable error of telling us what's wrong on the query.
3) Sql query and self-implementing finder method should also be provided as there are always cases that is hard to represent by a single HQL.
Interesting enough, we have also developed a primitive annotation base Model-DTO mapping tools. By certain annotations in the DTO side, it build DTO base on model object passed in, and incoming DTO back to model.
Basic idea on the DAO framework is shared, though in Chinese, in my blog: adrianshum.blogspot.com/ (in case u have interest)
Re: Similar things I have done
by
Oliver Gierke
Regards,
Ollie
Re: Similar things I have done
by
Tong Kuisong
1)Polyforms use convention: The parameters in method should order by name in NamedQuery.
2)We always add NamedQuery to Entity, so hibernate (or other JPA implementation) help us check the syntax during startup.
3)Polyforms has a function named query like QBC, developer write HQL like
<![CDATA[select u from User u
where 1=1
/~ and u.name like {%name%} ~/
/~ and u.email like {%email%} ~/
/~ and u.createdTime >= {createdTimeFrom} ~/
/~ and u.createdTime < {createdTimeDue} ~/
order by u.userName
]]>
and system will remove clause between /~ and ~/ when the parameter is null.</



Hello stranger!
You need to Register an InfoQ account or Login to post comments. But there's so much more behind being registered.Get the most out of the InfoQ experience.
Tell us what you think