Step Ahead Software releases open source exPOJO for persistence

Discussions

News: Step Ahead Software releases open source exPOJO for persistence

  1. exPOJO is a light weight yet powerful framework to assist in the implementation of the 'Exposed domain model pattern' outlined in "POJOs in ACTION". It also supplies 'convenience' features that most J2EE projects using JDO or Hibernate will benefit from. It's been released under LGPL, BSD or Apache 2 licenses according to a developer's preference. In order to explain the reason for exPOJO's (http://www.expojo.com) existence and why it is useful to developers it helps to dial up January 2006 on your time machine: At that time two significant things happened at Step Ahead Software: (i) we started migrating a sophisticated enterprise application from Hibernate to a JDO 2 implementation (JPOX). (ii) We bought a copy of Chris Richardson's "POJOs in ACTION." As the time machine rolled forward these two, seemingly unrelated, events started showing signs of synergy. We noticed that Hibernate and JPOX were doing roughly the same thing: persisting objects in an essentially transparent way. We also noticed that the exposed domain model pattern really rocks and is awesomely quicker than writing DAOs and EJBs. Transparent Persistence The exposed domain model pattern proposes a simple and elegant architecture for building applications built on POJOs: Plain Old Java Objects that know nothing about the persistence technology that is storing them (except in the case of Hibernate where some object identity attributes and methods need to be added - but let's ignore that for now and assume the persistence is completely transparent like in the JDO case). Using this pattern the presentation layer of an application retrieves model objects or collections of objects by calling methods on one or more "repository" classes or by navigating along relationships of objects already retrieved. The granularity of the repositories is at the developer's discretion. For larger enterprise applications it might be wise to create a separate repository for each area of concern of the application eg., UserRepository, OrderingRepository, AccountRepository but for small to medium sized applications a single repository may suffice. The repository classes use the query API specific to a specific persistence technology and so need to be implemented for each one that you wish to use. The presentation layer affects change in domain model objects via methods available on one or more "service" classes. Service objects are a great place to encapsulate business logic - they are not part of the presentation layer and they are separated from the domain model. Realization We realized two things when developing applications using services and repositories: (i) the applications can get quite sophisticated whilst maintaining an elegant and manageable code base; and (ii) the exposed domain model pattern goes a fair way to providing a ‘persistence agnostic’ application. This was a key factor when doing our port – we wanted to make sure that we were not locked into the new persistence framework and that we’d be able to port back to Hibernate or port to any other, possibly not yet developed, persistence technology in the future without too much effort. What we did was develop an in-house library that took this ‘agnosticism’ to the next level and added the ability to easily manage and maintain services and repositories and inject them into the current session’s active thread. The persistence technology independence is achieved by a simple generic PersistenceProvider interface (of which a Hibernate and JDO implementations are available). Each service class is written using the PersistenceProvider interface instead of the specific Session (Hibernate) or PersistenceManager (JDO) classes. This makes the service classes, where most of an application’s model changing code and business logic code are implemented, completely portable. The only thing required to port to a supported persistence technology is to write an implementation of your repository(s) for that particular technology. Each technology has its own query API and query semantics so we decided it wasn’t feasible to make repositories portable by creating an abstracted query API. exPOJO available to everyone We found this in-house library extremely useful and easy to use and thought it would benefit others in the Java community and so gave it the name exPOJO and decided to make it available for free under a LGPL, BSD or Apache 2.0 license (according to your personal preference). We have included a console based sample for which the only prerequisites are ‘ant’ and the JAR bundle available from the home page. Enjoy! Message was edited by: joeo@enigmastation.com
  2. except in the case of Hibernate where some object identity attributes and methods need to be added
    You don't need an identifier field for Hibernate, although you should have one if you want to use all features (detached objects). Also, EJB 3.0 entities require at least a field. You don't need any methods or property accessors if you don't want them. I only looked at the tutorial for a minute, this looks like a variation of the traditional DAO patterns. What's the difference between this and http://www.hibernate.org/328.html ? First I thought it would be similar to a pattern I'm using with Seam more and more: @Name("roleFactory") public class RoleFactory { /** * A List of all roles in the system. */ @Name("rolesList") @Scope(ScopeType.CONVERSATION) @AutoCreate public static class RoleList { @In protected EntityManager entityManager; @In private User currentUser; protected List roles; @Unwrap @Transactional public List getRoles() { if (roles == null) { entityManager.joinTransaction(); roles = (List)entityManager .createQuery("select r from Role r where r.assignedTo = :currentUser") .setParameter("currentUser", currentUser) .getResultList(); } return roles; } } } With this factory/DAO method, I can initialize a contextual variable named 'rolesList' on demand. Wherever I access this variable, be it in JSF value bindings or through contextual injection in another Seam component, I get the "current" (conversation scoped) list of role objects unwrapped from this inner class. If I need some other (contextual) variable to use as a query parameter, I use @In on a field of my RoleList inner class and Seam will inject it at call-time. This is not a complete replacement for a traditional DAO but it helps me to isolate the typical "current list of stuff" and "current instance of that class" data access cases - when "current" means application, session, conversation, or event scope. Everything that is more fine-grained goes into a traditional DAO, or I call the EntityManager directly in my action component. And, if I don't want the caching inside this manager class I can rewrite it so it is only called once, when the 'rolesList' contextual variable is first looked up and is empty: @Name("roleFactory") @Transactional public class RoleFactory { @In EntityManager entityManager; @Factory(value = "rolesList", scope = ScopeType.CONVERSATION) public List getRoles() { entityManager.joinTransaction(); return (List)entityManager .createQuery("select r from Role r order by r.accessLevel desc, r.displayName asc") .getResultList(); } }
  3. Addon: In case this isn't clear, the trick is that I never call any of these methods. I use the data like this: I can also do stuff like replace an implementation (e.g. for mock creation in testing), I only have to know the name and scope and put this in the classpath: @Name("roleFactory") @Transactional @Install(precedence = MOCK) public class MockRoleFactory { @Factory(value = "rolesList", scope = ScopeType.CONVERSATION) public List getRoles() { // Just return a mock list } } The default precedence of my previous class was APPLICATION, the MOCK precedence is higher and overrides the other component implementation. This also works for BUILT_IN and FRAMEWORK components of Seam, so you could even stub out an EntityManager... Sorry for highjacking this thread. I think the whole DAO pattern thing needs some new ideas (beyond "portability" between Hibernate and JDO) and I promise I'll finish the exPOJO tutorial now :)
  4. I only looked at the tutorial for a minute, this looks like a variation of the traditional DAO patterns. What's the difference between this and http://www.hibernate.org/328.html ?
    I have never used the pattern outlined in that link but after looking at it I was left thinking that it seems like overkill compared to how I've been developing using the exposed model pattern. I really believe that the whole DAO concept is an artifact left over from the days when we had to find a place to bury that dirty database access code (SQL, ResultSets etc,.) in nice little 'helper' classes to prevent us embedding the dirty SQL and ResultSet management code in the rest of our 'clean' classes. We also used DAOs to provide vendor insulation/abstraction.
    In these days, with such abundance of mature 'transparent' persistence technologies available, DAOs, to my thinking, are just a solution looking for a problem to solve but the problem has mostly already been solved by the 'transparent' in 'transparent persistence'.
    DAOs remind me of that clump of bones near the back of large whale skeletons that are the evolutionary remnants left over from a time when their ancestors used to walk on land - evolution has reduced them to nothing more than a non functional clump of bones but no one told the DNA that the whale will function just fine without them so it still puts them there.
    First I thought it would be similar to a pattern I'm using with Seam more and more:
    With DAO when you have a domain model of N classes you end up with (approximately~) N DAOs so you have now got ~2N classes to create and maintain. Sure, Seam might help you to manage that extra N classes more efficiently but why manage something efficiently that doesn't need to exist in the first place?
    The exposed domain model pattern gives you more like N + S + R classes to create and manage. S = number of service classes and R = number of repositories. We've got quite substantial enterprise systems where S = R = 1. We could split the existing service and repository into multiple services and repositories if we feel their size is getting unwieldy but that hasn't happened yet even though in one project N=70 and another N=56. If these get much bigger we might create some new repositories which would mean S = R = 2 which so we end up with N + S + R = N+4 which is still a lot more manageable and maintainable than 2N.
    In Chris Richardson's book, POJOs in ACTION, he writes "The first time I heard about this design technique my instant reaction was, 'It can't be right! You must use a facade.' ... We can eliminate the facade, which is just a middleman, and write less code and not worry about...". He recounted the anxiety he initially had when letting go of the perceived need for a facade (of which DAOs are an example) but he got over his anxiety, so did I and so will anyone else who wants to do things faster and smarter. It's natural to be anxious when you realize that you don't really need to do something that you've been doing for years - kind of like when switching from C++ to Java and not having to explicitly delete objects anymore - it freaks you out at first but you get over it.
    With this factory/DAO method ... This is not a complete replacement for a traditional DAO.
    You don't need a complete replacement for DAO. What you need is a convenient way of retrieving individual objects or collections of objects. This is provided via the repository methods. The other thing is that you need a way of creating and deleting objects and making changes your object model. This is provided via your service methods. Lazy loading occurs when you navigate along relationships of already retrieved objects so your UI can use natural object oriented semantics to retrieve whatever it needs from your domain model.
    exPOJO provides, among other things, a simple way of managing and accessing your services and repositories under a 'ModelExposer' object that is available via dependency injection to any object (UI, domain model, etc.,) that requires them.
  5. You don't need a complete replacement for DAO. What you need is a convenient way of retrieving individual objects or collections of objects. This is provided via the repository methods.
    Why is a "repository method" not a "data access object method"?
    The other thing is that you need a way of creating and deleting objects and making changes your object model. This is provided via your service methods
    What is the difference between a "service method" and a "data access object method"?
    Lazy loading occurs when you navigate along relationships of already retrieved objects so your UI can use natural object oriented semantics to retrieve whatever it needs from your domain model.
    Yes, pull lazy loading is what most data access layers (or ORM tools, or whatever) have been providing for years, nothing new. I'm trying to understand what makes things a "repository" or a "service" and why you wouldn't call that a data access object. When I'm saying data access object I don't mean the stuff from the J2EE blueprints from 1999 but simply an interface that I use to access the persistence layer of my system. Probably the most generic DAO would be the EntityManager interface. If my application is not very generic but needs quite specialized data access operations, I wrap an interface around my generic persistence layer, and I call that DAO. It's just a term these days that means "persistence layer API", it doesn't imply a particular implementation, not even if the persistence layer offers stateful (dirty checking, persistence context) or stateless services (dumb CRUD procedures).
  6. With DAO when you have a domain model of N classes you end up with (approximately~) N DAOs so you have now got ~2N classes to create and maintain.
    If that happens you just picked the wrong tutorial. The link I have posted earlier shows how you can use generics to avoid that. I'm sure there are many other strategies and so far they have all been known as data access object patterns (what is an object?). There is no single "The one-and-only DAO pattern".

  7. With DAO when you have a domain model of N classes you end up with (approximately~) N DAOs so you have now got ~2N classes to create and maintain.


    If that happens you just picked the wrong tutorial. The link I have posted earlier shows how you can use generics to avoid that. I'm sure there are many other strategies and so far they have all been known as data access object patterns (what is an object?). There is no single "The one-and-only DAO pattern".
    I'm referring to the clasic DAO pattern that is outlined by Sun in there blueprint at http://java.sun.com/blueprints/corej2eepatterns/Patterns/DataAccessObject.html When people come up with better patterns for managing persistence they'd do themselves a favor to avoid using the term DAO to avoid association with what many will understand to be the pattern outlined above - unless of course what they are producing is actually the same pattern but 'made easier to implement' via generics or annotations or whatever. Why 2N? The blueprint states that 'each BusinessObject corresponds to a specific DAO'. That's where the 2N comes from. Why should the second lot of N classes exist in the first place - even if you can make their definition easier via generics - you still need to instantiate them somehow either in code or declaratively (more XML or more annotations or whatever else people like to do 'more of' these days). 3N? Don't even think about it! That blueprint gets cringingly more painful with the addition of Data Transfer Objects (again one per business object) which brings us up to a 3N scenario. Let's not go there heh! I'm assuming the DAO version you use hasn't gone that extreme. 1N: Less is more I'm all for a 'less is more' approach. A Plain Old (PO) simple approach. The exposed model gives you that because your domain model objects are exposed directly to your UI elements as Plain Old Java Objects (POJOs) and are accessed via a very thin layer of, in its most minimal form, a single Service class and a single Repository. Differences between the Clasic DAO Pattern and the Exposed Domain Model Pattern (EDMP)
    - Classic DAO ends up with a DAO class for each domain model class. EDMP breaks this one-to-one relationship. - DAO promotes the idea of a separate DTO (Data Transfer Object) for each model object which is used to transfer model object attributes between the presentation layer and the DAO. The exposed domain model pattern uses the model objects themselves as the transfer mechanism! - DAOs contain both look up (queries), loading and saving persistence methods all in the one DAO class on a per model class basis. Exposed domain model pattern separates lookup methods (repository methods) from model changing methods (service methods) and does this at a granularity of the developer's choosing. Vendor independent code - similar to one of DAO's goals but done nicer One very convenient outcome of the separation of repository (lookup) and service (model modification) functionality is that most of the vendor specific code (query API, query language) ends up in the Repositories. A small amount of vendor specific code ends up in the service classes (makePersistent, begin transaction, commit transaction etc.,) but even some of this can be taken out with clever use of interceptors and transaction managers etc., exPOJO, among other things, takes this a step further by providing Service class(es) with access to a generic wrapper on the popular persistence technologies (JDO/Hibernate) to allow them to perform their job via methods available on an abstract PersistenceProvider class. exPOJO currently provides three concrete implementations of this class: one for Hibernate, one for JDO and one for a Mock implementation for testing your apps without rendering objects to a datastore. This means that your service classes, with all their model morphing code and any business logic you want to include, can be written using persistence technology agnostic code. These service classes are therefore instantly portable from one persistence technology to the next. Easy Mock Persistence A recent project at Step Ahead Software had 90% of the domain model, business logic and UI implemented and tested before we'd even written a single object to a datastore. All development to that point was done using Mock persistence with a MockRepositoryImpl. To switch over to using a real datastore we only needed to implement a single JdoRepositoryImpl - which was a fairly mechanical, no brainer exercise. Our ServiceImpl - with all the tested and verified business logic and model morphing code just worked without change in the new persistence capable environment. This app performs extremely fast and the code base is extremely compact. We found no need to incorporate Spring or any other jars other than the JPOX jars for persistence, exPOJO, log4j plus the UI framework jars (Echo2). It was all a bit 'eerily simple and clean' and we kept thinking "but it's meant to be harder than this!".
  8. Your explanation seems to be based on these 8 (7? 9?) year old blueprint examples. I'm not particularly interested in discussing how to fix something that nobody is using anymore. I thought this was something new because you used new terms. Maybe you need to define them better. Also fix the examples on your website, the code formatting is broken in many places.
  9. nothing outdated here...[ Go to top ]

    Only thing "new" in Chris' spiel is "Hibernate" and such like. But the DAO page he posted only came out in 2001, but complaining about the age of patterns is absurd, especially when you consider that the good old GoF book is now 11 years old (1995: http://www.amazon.com/dp/0201633612 )... when does a design pattern expire?... do they have a TTL?... a use-by date?... But exPOJO is thin layer of abstraction that removes the dependency on implementation, how can this be a bad thing?... it's the idea behind commons-logging and other frameworks. It just seems to me that Chris has made some handy code that will allow companies to go from implementation to implementation without pain. And with the flip-flopping of focus from JDO to Hibernate to whatever that some shops go through, how is it anything but helpful?... isn't a whole bunch of Java and Java projects about removing the vendor lock-in?...
  10. Your explanation seems to be based on these 8 (7? 9?) year old blueprint examples. I'm not particularly interested in discussing how to fix something that nobody is using anymore. I thought this was something new because you used new terms. Maybe you need to define them better. Also fix the examples on your website, the code formatting is broken in many places.
    I don't know the author of "POJOs in ACTION" personally and I'm not getting a commission from book sales but I thoroughly recommend you grab yourself a copy and read up all about it. The exposed domain model pattern is indeed very different to traditional DAO and the DAO variation you actively promote - for reasons which became apparent to me after I read your profile. It's not your fault you feel pressure to 'dis' every competing non JBoss product - I understand that it's part of your job description when you with the people you work with - still, it was probably worse back in the ole' days before astroturfing was embarrassingly removed from the job description.
  11. ROTFL
  12. awesome...[ Go to top ]

    ooh, more innovative things from Step Ahead. Looking forward to trying this out.
  13. Re: Exposed Domain pattern[ Go to top ]

    Clearly choosing an ORM that is totally specification-based is a key aspect to future-proofing your application, but being able to apply a further layer as Chris has done gives much flexibility. A welcome addition to the available patterns for people using ORMs, and should be seriously considered for anyone serious about not wanting to tie themselves to a particular ORM. -- Andy Java Persistent Objects (JPOX)
  14. Clearly choosing an ORM that is totally specification-based is a key aspect to future-proofing your application,
    I agree wholeheartedly on the benefits of choosing a specification-based ORM. This philosophy applies to all aspects of modern software development. The vitality of the servlet container world is a classic example of the benefits a specification-based approach brings.
    but being able to apply a further layer as Chris has done gives much flexibility.
    In our own experience exPOJO's provision of a generic transparent persistent layer has already given us a massive unforseen benefit even though we have no plans to change from the transparent persistence provider that we currently use. 'Transparent Persistence Provider' is exPOJO's term for the ORM (Hibernate/JPOX etc.,), object database, XML store or whatever technology is lying underneath the generic layer to provide the transparent persistence. The ability to switch quickly (by changing one line of code - or we could have even make it run time configurable) back and forth between the JPOX (in our scenario) persistence provider and exPOJO's built in Mock persistence provider delivers a massive benefit: Using the Mock persistence provider we can perform lightning fast memory only unit tests on our system, testing the execution of the model, the correct establishment of relationships and the business logic. Each individual test can be started in a fresh known state virtually instantly with the Mock persistence provider. This is in contrast to when unit testing with an ORM persistence provider where it can take a significant amount of time to establish a clean fresh state prior to running each test because it involves deconstructing the entire object model from the RDBMS, which can be a non trivial exercise when complex integrity constraints have been established especially if cyclic dependencies are involved. An easier way is to just delete the database and recreate the schema each time but that task takes significant time to complete. The mock persistence provider is a much better alternative for unit testing because it allows you to build and manage a object graph in memory which can be instantly abandoned prior to starting the next test.