Home

News: ORM and the misleading DAO pattern

  1. ORM and the misleading DAO pattern (65 messages)

    The DAO layer offers a great enhancement in the process of software development. It effectively decouples the business layer from the persistence mechanism. For this reason it gives robustness to our application's architecture and flexibility when it comes to the unavoidable evolutions and branches of our work. In fact, changing the way data is persisted (e.g. JDBC - possibly between different vendors, XML, files) is simply a matter of writing new DAO implementations in a well isolated layer. But with the introduction of an ORM, well, things change quite a lot. Imagine the following scenario: we've got an application developed with a well-isolated DAO layer that interacts with a database via JDBC. Now we want to switch to an ORM solution (e.g. Hibernate) by writing a new DAO implementation which makes calls to our ORM. Sounds good ... but wait! How about the way the business and the view layers are handling the domain objects? There is nothing in these layers to prevent developers from changing a domain object just loaded by the DAO layer. With a JDBC-oriented DAO in mind the developer is free to change anything about a loaded object, maybe for view reasons or for in-memory elaborations. As far as the object is not explicitly updated through calling the DAO again, one thinks the object to be just an in-memory (transient) copy of the original persisted one. This is not the case when using an ORM approach! Switching to an ORM often implies that the object loaded and passed to the business and view layers is persistent; so any change to its properties, any change to relations with other objects will be automatically made persistent, no matter if the DAO is called again. On the other hand switching from an ORM-oriented to a JDBC-oriented DAO (or XML, file) will soon fail because of the missing DAO update calls that an ORM approach does not require. In conclusion the DAO pattern does not isolate well; business and view layers must know if they are handling persistent (automatically updated) or transient (updated upon an explicit request) domain object. Some suggest never to expose directly the persistent object, but a transient copy of them (through another set of classes or by detaching objects). However, I prefer to deal with a poorly isolated DAO layer (thus giving away with the JDBC-ORM switching option) than giving away with the advantages of handling persistent objects directly. I mean, all the overhead working needed to detach/reattach objects or to copy properties back and forth between persistent and transient object almost kills the ORM choice. Better to have a full ORM with a half DAO than a swichable DAO with a half ORM, IMHO. Do we have to split the DAO pattern in two in order to have a clearer distinction? Or am I missing something? I'd appreciate your opinions. References:
    1. Rationale of using DAO layer with ORM solution
    2. Of Persistence and POJOs: Bridging the Object and Relational Worlds
    Message was edited by: joeo@enigmastation.com

    Threaded Messages (65)

  2. I do agree, and also what about the reverse problem. Suppose I wrote a perfect loosely coupled DAO, that returns to my business methods model objects. If I first wrote the DAO with an ORM I will have a persistent object and all my work will be automatically updated on the relational DB. If then I switch to a JDBC based DAO I will loose this, and only with the use of AOP I will be guaranteed that the model will be correctly updated. So in my opinion the only use-case for a completely switchable (between ORM and plain JDBC or iBatis) DAO pattern is with read-only model objects.
  3. http://www.theserverside.com/news/thread.tss?thread_id=39111#201668 It a good practice to isolate persistence API calls in a layer, we used to qualify this layer as DAO. I don't like the "Data" of Data Access Object pattern. Community is trusting more and more on Domain Model design (when needed) because we can easily solve persistence problems with frameworks like Hibernate, Toplink, … and EJB3, Domain Model is Data AND business behaviour using complex object network. UnitOfWork pattern (EJB3 Entity Manager, Hibernate Session, Toplink UnitOfWork), is able to handle many sql Insert, update, delete SQL statements only by providing _Persistence by reachability_ and dirty checking features on our object network. CRUD is not necessary anymore, this isolation layer is essentially handling READ operations, to obtain a root entity from which you can reach other objects... You don’t have to code any UPDATE, DELETE or INSERT, just delegate to persist, merge, remove methods. So DAO becomes EAO (Entity Access Object). CRUD becomes PRADR (Persist, Retrieve, Attach, Detach,Remove, knowing that persist, detach, attach, remove is natively done by EntityMaganer, nothing to do!). Anthony
  4. stateless context[ Go to top ]

    I think the orm tools don't bring any added value, I am developping application using swing client , the business layer is behind webservices, so I can not Imagine in this case how to keep object in session and have the PRADR !!!!
  5. Part of the problem with any "DAO" disscussion is that there are two flavours of the pattern in common use: 1) using a set of classes handle generic persistence mechanism for a related group of persisted classes, and some sepcific query evaluations. 2) having a one to one mapping between persisted classes and "DAO" classes. (1) is typically a very thin layer sitting on top of an ORM because it is relying on the usual ORM facilities such as class mapping metadata and persistence by reachability. (2) Should only be used where it is actually neceassary to persists each class individualy by hand e.g. for direct JDBC persistence. Thus each particualr DAO pattern only gives the ability to migrate between simmilar persistence paradigms - it wont help much in say moving from an ORM to raw JDBC (well not unless you started out with a huge amount of denceny in your DAO layer). aul.
  6. Correction: I horribly misspelt "redundency". Paul.
  7. All we want is an "Abstraction" to Data Access... My proj. has a generic DataAccessUtil... which hv all method like: DataAccessUtil.create(Classname, PK) DataAccessUtil.find(Classname, PK) DataAccessUtil.query(Classname, NamedQuery, ParameterList); etc... I'm using Hibernate now, but was switched from JDO2 before, and i know it work perfectly. Think about ORM (or even obj-xml-mapping) did their job right, DAO really does not bring any extra value...(compare with the effort of implementing DAO) just my 20 cents
  8. Here's a mind blowing thought: maybe not all architectures and approaches are suitable for all situations. Oh my god, did I just say that? Really? Wow. Mindblowing. Maybe the real answer in the persistence layer VS hard-coded-SQL is that both sides are right depending on the situation. Maybe people can't imagine that there are other scenarios in the world where different approaches are warranted. Wow. Except JDO. JDO was always a bad idea and anyone who bought into really wasted a lot of time, money and reputation. - Don
  9. Patterns come from pre-solved problem, are an "experience" repository that can help us solving similar ones. So we don't need to use a pattern if we can see that instead of helping us is going to give use more problem than the problem is it trying to solve. In this case using the DAO pattern we should always use "Transfer Object" between the business layer and the data layer, but this mean that using an ORM we should decide to loose one of the main feature of an ORM and return them detached. So what to do ? Use a DAO style but document that object are not detached ? Don't use a DAO ? Which is your design style ?
  10. I couldn't agree more. If you are only dealing with a single database, simple transactions, don't need to worry about exposing your business facade to multiple clients (web services, web application "view") then why not take the "simplified" approach?? However, if you've got multiple databases, complex transactions and/or multiple clients this approach quickly breaks down. Sometimes "more code" is warranted. Often, it's not. The author of the column should check out "POJOs In Action". It's not a "great" book, but it outlines all of the different options you really have available and should consider when building these types of applications. What is being describing is the "exposed domain model" pattern. I think the book gives a reasonable rundown of it's pros/cons.
  11. except for JDO[ Go to top ]

    Keep cool Donald...
  12. Another angle...[ Go to top ]

    ORM and DAO's do seem like overkill but the combimbination seems to make sense if you would like to abstract not ONLY the underlying data store (Oracle or SqlServer etc..) but the ORM itself (Hibernate or Toplink...). So I guess there is value in using both.. But where I see the problem with the dao -> ORM migration is the interface itself changes between an app using an ORM and an app that does not. For instance, in a traditional DAO pattern, I may have method signaures in UserDAO interface such as: saveUser(...) addUser(...) deleteUser(...) etc that are implemented by JdbcUserDAO class. But after the ORM is introduced and I write another TopLinkUserDAO implementation that implements UserDAO and may require an addOrModifyUser(..) method instead. While it should not be difficult to change the signature, it kind of defeats the purpose of having an interface in the first place. That is why I am wondering if the DAO interface concept works across the manual(Jdbc) persistence and transparent (Hibernate/Toplink) persistence divide.
  13. Except JDO. JDO was always a bad idea and anyone who bought into really wasted a lot of time, money and reputation.
    Do grow up. You've justed wasted a lot of time, money and reputation on that FUD Donald.
  14. Except JDO. JDO was always a bad idea and anyone who bought into really wasted a lot of time, money and reputation.

    Do grow up. You've justed wasted a lot of time, money and reputation on that FUD Donald.
    Perhaps it is you Andy who needs to grow up and become more tolerant to different opinions. I agree that the JDO idea is bad. However particular implementations might be good. So far I saw only good JDO which are effectively ORMs with JDO API.
  15. I agree that the JDO idea is bad. However particular implementations might be good. So far I saw only good JDO which are effectively ORMs with JDO API.
    So perhaps not a bad idea then... What exactly is supposed to be the bad idea about JDO - perhaps the idea that not everyone developing in Java wants object persistence to be in the hands of relational database vendors? I had always assumed that Java was about providing choice for developers... perhaps I was wrong.
  16. Except JDO. JDO was always a bad idea and anyone who bought into really wasted a lot of time, money and reputation.

    - Don
    Sorry, wrong. I am at least one person who has bought into JDO and saved a lot of time and money (and gained reputation) as a result.
  17. Damnit Steve, were you on a plane today? I lost a big bet on your response time. Snap to it next time, will ya? - Don
  18. Damnit Steve, were you on a plane today? I lost a big bet on your response time.

    Snap to it next time, will ya?

    - Don
    Sorry - I was indeed travelling! I will attempt to do better in future.....
  19. What is misleading?[ Go to top ]

    Consider using a super layer type pattern with your DAO factory. This will give you the flexibility to switch between JDBC, Hibernate or EJB3 without creating havoc in your domain layer. Hibernate makes dealing with detached objects a very easy task. Auto-wiring DAOs to your POJO Facades / Services via Spring give you a very clean solution. Using Spring Hibernate templates makes this task of dealing with detached objects much easier. You business API offers a contract. Assuming you are using a bridge pattern, your view shouldn't be effected, nor should have to accomodate changing your underlying persistence layer that your isolated DAOs utilize.
  20. Consider using a super layer type pattern with your DAO factory. This will give you the flexibility to switch between JDBC, Hibernate or EJB3 without creating havoc in your domain layer.

    Hibernate makes dealing with detached objects a very easy task. Auto-wiring DAOs to your POJO Facades / Services via Spring give you a very clean solution. Using Spring Hibernate templates makes this task of dealing with detached objects much easier.

    You business API offers a contract. Assuming you are using a bridge pattern, your view shouldn't be effected, nor should have to accomodate changing your underlying persistence layer that your isolated DAOs utilize.
    1.JDBC is stone-aged. Consider the advance query language, criteria, cache etc offered in ORMs, why the hell would anyone jump back to plain SQL? It's just like assembly in 31st century! 2.What's the point of making your application able to use different ORM solutions? Build a bridge, a bridge for a bridge, a bridge for a bridge for a bridge.... hmmmm...
  21. 1.JDBC is stone-aged. Consider the advance query language, criteria, cache etc offered in ORMs, why the hell would anyone jump back to plain SQL? It's just like assembly in 31st century!
    People still use assembly, even in the 21. century. Not all applications are CRUD-like web applications. I can give you a concrete example. I work for a telco. Most of our applications use some form of ORM. Our real-time applications don't. Our chosen ORM library is too sluggish - and we have measurements to back that up. This doesn't mean we haven't saved a lot of resources by using ORM where it is appropriate.
  22. Can you post a short code example of what you are talking about? I don't understand the problem. For example, in my apps I usually extend Spring's HibernateDaoSupport to create DAOS. So let's say I have a User domain model POJO, a UserDao inteface with a method called get(Long id) and an implementation of UserDao using HibernateDaoSupport. And then assume userDao is an instnace of the UserDao implementation. If I have this code: User user = userDao.get(new Long(1)); user.setFirstName("Something Else"); That change is not going to be persisted to the database. If It wanted it to be, I would have to do this: User user = userDao.get(new Long(1)); user.setFirstName("Something Else"); userDao.save(user); So what are you talking about?
  23. If I have this code:

    User user = userDao.get(new Long(1));
    user.setFirstName("Something Else");

    That change is not going to be persisted to the database. If It wanted it to be, I would have to do this:

    User user = userDao.get(new Long(1));
    user.setFirstName("Something Else");
    userDao.save(user);
    This depends on how you configured Spring to manage the Hibernate session. If you use the "session-per-request" Hibernate implementation patter http://www.hibernate.org/42.html & http://www.hibernate.org/43.html e.g. using the popular OpenSessionInViewInterceptor of Spring, then the save() call is not necessary since the session will be automatically synchronized with the database the moment the session is closed. This is called automatic dirty checking.
  24. Ok, when then that is really the problem. I guess the article title should really be "ORM+OpenSessionInView breaks DAO pattern."
  25. Ok, when then that is really the problem. I guess the article title should really be "ORM+OpenSessionInView breaks DAO pattern."
    What about FlushMode=COMMIT in your InViewOpened-Session?
  26. Ok, when then that is really the problem. I guess the article title should really be "ORM+OpenSessionInView breaks DAO pattern."
    I think you're right. The way many people implement OpenSessionInView violates the contract a DAO layer should uphold. Typically, to implement it, you'd have a servlet filter that wraps the request-response processing with a closing call to the ORM session that flushes everything to the db. The session knows what "everything" means because it's really a container. The direct access to the ORM session from the web tier means we have a persistence action that doesn't go through the DAO layer and so it breaks the encapsulation this layer provides. Anytime you expose a low level API outside of it's higher level wrapper, you make it impossible for the higher level wrapper to guarantee it behaves predictably. So the real title should maybe be: "Using the ORM directly session in the servlet tier breaks the DAO pattern". To salvage the situation you'd have to have the servlet filter invoke something in the DAO layer that does the "flush everything" operation. The problem is that traditionally the DAO layer doesn't do this and making it do it is akin to writing your own ORM tool.
  27. Generics and DAO[ Go to top ]

    "Tools like Hibernate already provide database portability, so persistence layer portability shouldn't be a driving motivation for interfaces. However, DAO interfaces make sense in more complex applications, when several persistence services are encapsulate in one persistence layer..." With java 1.5 generics: http://www.hibernate.org/328.html
  28. I can see from this piece of code
    User user = userDao.get(new Long(1)); user.setFirstName("Something Else");
    that the "user" object now is a persistent object, so any change to it will lead to a db update when the session will be closed. The only configuration of Hibernate that will not update the "user" object with the new value for firstName property is with the session-per-method antipattern (please read hibernate docs for this), but I don't think you are using them. The only real use for save is to change the object state from "transient" to "persistent". Saving a persistent object is a no-operation call:
    public Serializable save(Object obj) throws HibernateException { if (obj==null) throw new NullPointerException("attempted to save null"); Object object = unproxy(obj); //throws exception if uninitialized EntityEntry e = getEntry(object); if ( e!=null ) { if ( e.status==DELETED ) { forceFlush(e); } else { log.trace( "object already associated with session" ); return e.id; } } Serializable id = saveWithGeneratedIdentifier(object, Cascades.ACTION_SAVE_UPDATE, null); //id might be generated by SQL insert reassociateProxy(obj, id); //TODO: move into saveWithGeneratedIdentifier()? return id; }
    (this is from Hibernate 2.1.x SessionImpl code)
  29. I still don't get it. What if I DO want my setFirstName() to take effect right away? If calling save() does no-op, does ending the current session the only way to make the persistence happen? Ric
    I can see from this piece of code

    User user = userDao.get(new Long(1));
    user.setFirstName("Something Else");

    that the "user" object now is a persistent object, so any change to it will lead to a db update when the session will be closed.
    The only configuration of Hibernate that will not update the "user" object with the new value for firstName property is with the session-per-method antipattern (please read hibernate docs for this), but I don't think you are using them.
    The only real use for save is to change the object state from "transient" to "persistent".
    Saving a persistent object is a no-operation call:

    public Serializable save(Object obj) throws HibernateException {

    if (obj==null) throw new NullPointerException("attempted to save null");

    Object object = unproxy(obj); //throws exception if uninitialized

    EntityEntry e = getEntry(object);
    if ( e!=null ) {
    if ( e.status==DELETED ) {
    forceFlush(e);
    }
    else {
    log.trace( "object already associated with session" );
    return e.id;

    }
    }

    Serializable id = saveWithGeneratedIdentifier(object, Cascades.ACTION_SAVE_UPDATE, null); //id might be generated by SQL insert
    reassociateProxy(obj, id); //TODO: move into saveWithGeneratedIdentifier()?
    return id;

    }


    (this is from Hibernate 2.1.x SessionImpl code)
  30. I still don't get it. What if I DO want my setFirstName() to take effect right away? If calling save() does no-op, does ending the current session the only way to make the persistence happen?
    Yes, sure, anything that do a synchronization (close, flush,commit).
  31. now, whats the problem[ Go to top ]

    I think another valid alternative is to forget about DAOs altogether. After all, an ORM is located higher on the abstraction stack than DAOs. If you cover up a higer-level concept with a lower-level one, you naturally lose the advantages of the former. Therefore, here are my sugestions, depending on your preferences:
    • if you want the full benefit of the ORM, including Object query language etc. use a lightweight facade to improve testability, centralize API access, etc., which passes back the "managed" objects (aka entities). Be aware that, if you later want to switch to a more primitive technology (like plain JDBC, but why in the world would you want to do that??), you will likely have to rewrite parts of your app, as you mention
    • if you dont need the ORM advantage, use some DAO layer which wraps plain JDBC
  32. Switching to an ORM often implies that the object loaded and passed to the business and view layers is persistent; so any change to its properties, any change to relations with other objects will be automatically made persistent, no matter if the DAO is called again.
    It depeneds on Your, actual, implementation of your DAOs. I think You overcomplicated the problem. First of all: changes are persisted only if done in the same session. If You use detached objects You have explicity update/reatach Your POJOSs. And this is the case in the most applications I have seen. Yust take a look at spring DAO support. Using this You can easy implement plugable DAO implementations using JDBC/HB/JDO/JPA/iBatis etc. Artur
  33. I prefer to think that an ORM tool (like Hibernate, Toplink or iBatis) are already a DAO! They access data through objects, they abstract the way data is been kept, even when in most cases, works only for database. But, look to some hibernate code: 90% of them has NO reference to database operations, sintaxe, SQL or whatever. So, Hibernate _is_ your DAO pattern implementation. There's no reason to add another layer between it and the business/view layer. Let's use Hibernate/iBatis/Whatever_ORM_tool_you_want_to_use the way it is. Let's take advantage of all the API and functionalities and get the best performance we can achieve. :)
  34. I prefer to think that an ORM tool (like Hibernate, Toplink or iBatis) are already a DAO! They access data through objects, they abstract the way data is been kept, even when in most cases, works only for database.

    But, look to some hibernate code: 90% of them has NO reference to database operations, sintaxe, SQL or whatever. So, Hibernate _is_ your DAO pattern implementation. There's no reason to add another layer between it and the business/view layer.

    Let's use Hibernate/iBatis/Whatever_ORM_tool_you_want_to_use the way it is. Let's take advantage of all the API and functionalities and get the best performance we can achieve.

    :)
    I would rather you use the generic DAO like he said in this article, but he used a lot of "tricks" to explain the same functionality that can be explained with only a POJO that will contain some annotations with a pair of named-queries and only a DAO Generic doing the findByNamedQuery(String param, Map values). The author has a great concern about the logic using a lot of daos to do the same work, but I don't agree with the complexity of his work to explain something simple. Spring is simple, but it is not necessary a hard work to make it understandable. See you Dalton Camargo
  35. Agreed[ Go to top ]

    +1
  36. I dunno...[ Go to top ]

    Seems to me if you have a DAO layer that behaves differently between using an ORM and normal JDBC, you don't have a very good DAO layer. Sounds like the DAO is exposing implementation details that it's specifically designed to to avoid exposing. Now, this issue is perpindicular to whether you should use a DAO layer at all along with using an ORM (as has already been discussed). But the DAO layer isn't, IMHO, supposed to hide simply the database being used, but the entire persistence mechanism (JBDC, ORM, OODB, et al).
  37. a bad dao[ Go to top ]

    I think you said it more precisely... If the DAO changes it is not a 'good DAO' to begin with. I agree. Problem is that when an app uses Jdbc for persistence, the DAOs tend to become very granular. Atleast, they evolve towards that state. And so, in terms of migrating from a manual persistence to a transparent persistence we have to change the DAO substantially to make it a transparent-persistence ready. Maybe that has been just my experience but I'm seeing a lot of changes going from JDBC to Hibernate persistence in terms of DAO changes.
  38. I agree that DAO does not fit well in a ORM context but I totally disagree that DAO layer offers a great enhancement in SW development. My opinion on DAO might be affected by a misunderstanding of the pattern, but anyway (please forgive me, I always used an ORM approach since java 1.0.2). I think that DAO is really unuseful because: 1. A single DAO class manages a single domain object 2. A DAO class manages "transaction" boudary at method level (Maybe other but not relevant, first 2 are sufficient to show a poor non-solution) 1. DAO, in my understandig, by definition, manages a single object class. Well, life is a little more complicated than that. How to manage a Book-Author relationship ? With 2 DAO ? Oh my God !! We already have our wonderful POJO class Author { private Collection books; } Why should we need a DAO to wrap Book and Author ? A real mistery. 2. DAO, always in my understanding, by definition, manages datastore access with method granularity. Again life, and business logic, is a little more complicated. What about an user operation involving the modification of multiple attributes ? We end up with multiple JDBC transactions ? Even worse is the case when you need to update different classes with a single user interaction (e.g. command pattern) in a single atomic transaction. DAO is able to face with this ***extremely*** common scenarios ? Ready to learn, by I don't think so. Guido P.S. Why JDO is so bad ? I think that english word for this is fud.
  39. What about an user operation involving the modification of multiple attributes ? We end up with multiple JDBC transactions ?
    Even worse is the case when you need to update different classes with a single user interaction (e.g. command pattern) in a single atomic transaction.

    DAO is able to face with this ***extremely*** common scenarios ?
    Why is this so difficult? public Object updateObject(Object object) throws ServiceException { Connection conn = null; try { conn = getPooledConnection(); aDao.update(object.getA(), conn); bDao.update(object.getB(), conn); cDao.update(object.getC(), conn); dDao.update(object.getD(), conn); eDao.update(object.getE(), conn); commit(conn); } catch (DaoException e) { rollback(conn); throw new ServiceException(e); } finally { close(conn); } return object; }
  40. Why is this so difficult?

    public Object updateObject(Object object) throws ServiceException {

    Connection conn = null;

    try {

    conn = getPooledConnection();

    aDao.update(object.getA(), conn);
    bDao.update(object.getB(), conn);
    cDao.update(object.getC(), conn);
    dDao.update(object.getD(), conn);
    eDao.update(object.getE(), conn);

    commit(conn);

    }
    catch (DaoException e) {
    rollback(conn);
    throw new ServiceException(e);
    }
    finally {
    close(conn);
    }

    return object;
    }
    Oh yes, but in which class you define this updateObject(..) method ? Is a DAO for which domain class ? How do you get references to aDao, bDao, etc ? OK, you can stretch pattern to better fit your needs, but I think that an update(Object o, Connection conn) is not a proper DAO method. From my understanding of the pattern (well, there are many examples in open source world that work like this), persistence aspects, from acquiring a datastore connection to its release, are enclosed within a single method. Trying to solve the problems I sketched, you will end up with your own ORM. Guido.
  41. Oh yes, but in which class you define this updateObject(..) method ? Is a DAO for which domain class ?
    It's a specifically confusing example because he used Object, implying it works for anything, rather than ClassX, meaning it's class specific. But change it to "ClassXDAO.update(ClassX cx, Connection conn)", and it basically works.
    How do you get references to aDao, bDao, etc ?
    However you want: hard code them, inject them, use a factory, whatever floats your boat.
    OK, you can stretch pattern to better fit your needs, but I think that an update(Object o, Connection conn) is not a proper DAO method.
    Replace Object with ClassX, and it's a peachy DAO method.
    From my understanding of the pattern (well, there are many examples in open source world that work like this), persistence aspects, from acquiring a datastore connection to its release, are enclosed within a single method.
    You can do that depending on the application. Most find it better to use some higher level mechanism to demarcate transactions than doing it within the actual DAO methods. This makes it easier to mix and match the DAO methods (IME).
    Trying to solve the problems I sketched, you will end up with your own ORM.
    ORMs, as the term is typically used, are tools designed to do the mapping and query generation for you. You may use an ORM on one side of a DAO layer, but implementing a DAO layer by no means suggests you're implementing a "generic" ORM tool. If you want to be pedantic, then, yes a DAO layer IS an ORM layer, as it maps Objects to a Relational Database, but in fact that's only true if the back end the DAO is supporting just happens to be Relational. DAOs can front any data source: RDBMS, OODBs, flat files, whatever. It's just a way for your business objects to get data. DAO is simply a pattern. It's a layer interspersed between the persistence layer and business layer to better seperate the concerns. Whether you chisel it out by hand, use a code generator, an ORM tool, Spring Template or iBatis is pretty much moot. The problems presented in this discussion are related to using an ORM on the back end, but letting ORM "aware" or "alive" objects pass through to the business layer, when in fact they should probably be more "stupid" value objects. When using a JDBC based DAO, you don't get the side effects reflected to the DB should you change an object returned from the DAO, but not actually send it back for the update. The problem here is not with the DAO pattern per se, it's with leaking details of the back end implementation through the DAO layer which undermines the seperation of concerns that it is put in place to provide.
  42. It's a specifically confusing example because he used Object, implying it works for anything, rather than ClassX, meaning it's class specific. But change it to "ClassXDAO.update(ClassX cx, Connection conn)", and it basically works.
    No, I use Object specifically. All of my DAOs extend an AbstractDao. The AbstractDao has all of the public methods - select(long id, Connection conn), update(Object o, Connection conn) etc. The DAO subclasses have only six or seven protected contract methods that return PreparedStatements prepareUpdateStatement(Object o, Connection conn), prepareSelectStatement(long id, Connection conn), etc.

    There is also a method to parse an object (any kind of object the subclass wants) from the ResultSet. It works very nicely because all of my error handling, ResultSets and executions are handled in the public methods of the super class. It's very clean plus all of my DAO subclasses are generated from the database spec.
    Most find it better to use some higher level mechanism to demarcate transactions than doing it within the actual DAO methods.

    This makes it easier to mix and match the DAO methods
    Exactly! DAO should not create, commit or rollback the connection.
  43. It's a specifically confusing example because he used Object, implying it works for anything, rather than ClassX, meaning it's class specific. But change it to "ClassXDAO.update(ClassX cx, Connection conn)", and it basically works.
    No, I use Object specifically. All of my DAOs extend an AbstractDao. The AbstractDao has all of the public methods - select(long id, Connection conn), update(Object o, Connection conn) etc. The DAO subclasses have only six or seven protected contract methods that return PreparedStatements prepareUpdateStatement(Object o, Connection conn), prepareSelectStatement(long id, Connection conn), etc.

    There is also a method to parse an object (any kind of object the subclass wants) from the ResultSet. It works very nicely because all of my error handling, ResultSets and executions are handled in the public methods of the super class. It's very clean plus all of my DAO subclasses are generated from the database spec.
    Most find it better to use some higher level mechanism to demarcate transactions than doing it within the actual DAO methods.

    This makes it easier to mix and match the DAO methods
    Exactly! DAO should not create, commit or rollback the connection.
  44. What about the GenericDAO Pattern? I could write an loosely coupled series of methods in a GenericDAO class that can manage JDBC queries from a QueryBundle resource manager (i.e. the queries are on a separate file, not in the code) and the connection from a ConnectionBroker resource manager. The queries come in a variety of flavours: I can retrieve a populated bean, a java.util.List of beans, an array[] of beans... and if I'm not interested in beans I can get java.util.Map generic beans as well. The same for inserts, updates and deletes. It's still a work in progress, but I used it in very big projects (>3Mb of source code) without efforts and with excellent runtime performances.
  45. Oh yes, but in which class you define this updateObject(..) method ?
    I might say the Service object.
    How do you get references to aDao, bDao, etc ?
    Inversion of control or a factory.
    From my understanding of the pattern (well, there are many examples in open source world that work like this), persistence aspects, from acquiring a datastore connection to its release, are enclosed within a single method.
    Not at all! Transaction coordination is a service responsibility. Resource allocation can be done by the service or, much more elegant, shared using a IoC container.
    Trying to solve the problems I sketched, you will end up with your own ORM.
    ... or use Spring ...
  46. Oh yes, but in which class you define this updateObject(..) method ?

    I might say the Service object.
    So you need a service layer coordinating DAO that knows about java.sql.Connection.
    From my understanding of the pattern (well, there are many examples in open source world that work like this), persistence aspects, from acquiring a datastore connection to its release, are enclosed within a single method.

    Not at all! Transaction coordination is a service responsibility. Resource allocation can be done by the service or, much more elegant, shared using a IoC container.

    OK, a lot real of world applications work as I described. I agree that Txn (in broad sense) must be put at service level, but, if you have quasi-tansparent persistence provided by ORM, what is the DAO added value ? Independence from RDBMS ? It's a job ot the ORM tool. Datastore technology independence ? Hmmm, not so sure if you need some update(ClassX x, java.sql.Connection conn) and there is JDO for this. Other ? Please list.
    Trying to solve the problems I sketched, you will end up with your own ORM.


    ... or use Spring ...
    To do what ? The topic was about the usefulness of a DAO layer when your domain (persistent) object are implemented using an ORM tools that allows POJO persistence. Recalling the Author-Book example, what is better, this: class Author { Collection books; public Collection getAllBooks() { return books; } } so you can do this: Author a = .. Collection books = a.getAllBooks(); or this: class AuthorDAO { public Collection findAllBooks(Object authpk, java.sql.Connection conn); and do this: Object authpk = ... AuthorDAO adao = ... Connection conn = .. Collection a_books = adao.findAllBooks(authpk, conn); The nice thing is that using DAO pattern to wrap ORM tool your public Collection findAllBooks(Object authpk, java.sql.Connection conn); should look like: Author auth = ...(somehow form authpk) Collection books = a.getAllBooks(); return books; Where is the gain ? Guido
  47. So you need a service layer coordinating DAO that knows about java.sql.Connection
    No, you can easily write a Java Proxy or a Spring/AspectJ interceptor around the service that creates a connection at method start, closes and commits at method end and rollbacks in case of exception.
    OK, a lot real of world applications work as I described.
    I agree that Txn (in broad sense) must be put at service level, but, if you have quasi-tansparent persistence provided by ORM, what is the DAO added value ?
    Independence from RDBMS ? It's a job ot the ORM tool.
    Datastore technology independence ? Hmmm, not so sure if you need some update(ClassX x, java.sql.Connection conn) and there is JDO for this.
    Other ? Please list.
    The DAO added value is in creating an indirection between the [data access logic, persistence technology] and the services. In this way you could switch between JDO, Hibernate and JDBC for instance (provided you have a real reason for doing so). Moreover, a DAO method can be shared between multiple services.
    To do what ? The topic was about the usefulness of a DAO layer when your domain (persistent) object are implemented using an ORM tools that allows POJO persistence.
    Recalling the Author-Book example, what is better, this:

    class Author {
    Collection books;

    public Collection getAllBooks() {
    return books;
    }
    }

    so you can do this:
    Author a = ..
    Collection books = a.getAllBooks();

    or this:
    class AuthorDAO {
    public Collection findAllBooks(Object authpk, java.sql.Connection conn);

    and do this:

    Object authpk = ...
    AuthorDAO adao = ...
    Connection conn = ..
    Collection a_books = adao.findAllBooks(authpk, conn);


    The nice thing is that using DAO pattern to wrap ORM tool your
    public Collection findAllBooks(Object authpk, java.sql.Connection conn);
    should look like:

    Author auth = ...(somehow form authpk)
    Collection books = a.getAllBooks();
    return books;


    Where is the gain ?


    Guido
    Again: share the data access logic between multiple services, hide the technology you use for retrieving the data graph.
  48. What about an user operation involving the modification of multiple attributes ? We end up with multiple JDBC transactions ?
    Not necessarily. It all depends on the implementation correctness.

    Even worse is the case when you need to update different classes with a single user interaction (e.g. command pattern) in a single atomic transaction.

    DAO is able to face with this ***extremely*** common scenarios ?
    Ready to learn, by I don't think so.
    Down to the examples: if Spring's HibernateTemplate is used as DAO then we have all the bad things you have mentioned. But if SessionInjection and proper transaction wrapper amd management were used then life is good. http://www.onjava.com/pub/a/onjava/2005/05/18/swingxactions.html?page=1
  49. The problem is that people think persistance =only dao, which isn't true. Persistance needs two type of components : the DAOs to interact with the repository and the synchronization code (better handled as a cross cutting concern, *cough*aspect*cough*). When you use pure JDBC, typically the synchronization code isn't handled as a cross cutting concern and mixed with the DAO and this where things begin to become complicated. Its methods get fine grained and the class is completely bloated. So in short, DAO isn't the problem but the way data synchronization is handled in pure JDBC application. A DAO by design should be very thin and should only convert specifi exceptions and transaction concepts into a more general API. This is exactly the purpose of Spring templates objects.
  50. Yes, I do think there's confusion between ORM and DAO. If your data model essentially mimics your database, and the database is under complete control of the application, ORM is an easy way to go, I suppose. I'm working on an app, though, that uses a database that's a mess (because half a dozen other apps use it), and I don't want a Java object representation of that mess working its way into my front end, which is why I prefer using transient "transfer" POJOs and passing them to a DAO layer. Now if we decide one day to clean up that mess, I'm just re-writing DAOs. The poor folks that used ORM generated objects will have to re-write their entire application.
  51. How about the way the business and the view layers are handling the domain objects? There is nothing in these layers to prevent developers from changing a domain object just loaded by the DAO layer. With a JDBC-oriented DAO in mind the developer is free to change anything about a loaded object, maybe for view reasons or for in-memory elaborations.

    As far as the object is not explicitly updated through calling the DAO again, one thinks the object to be just an in-memory (transient) copy of the original persisted one.

    This is not the case when using an ORM approach!

    Switching to an ORM often implies that the object loaded and passed to the business and view layers is persistent; so any change to its properties, any change to relations with other objects will be automatically made persistent, no matter if the DAO is called again.
    Automatic (transparent) updates do present this problem of unintentional updates that can potentially cause data corruption in a subtle way. An ORM framework, which does not do object tracking or allows for its suppression can help avoid such problems. With such a solution, you get all the advantages of code simplification facilitated by the use of an ORM framework and you also get full flexibility in terms of how you get to use the queried objects in your application because these objects are not tied to or tracked by the ORM framework. JDX is one such ORM product. -- Damodar Periwal Software Tree, Inc. Simplify Data Integration
  52. Are DAOs an antipattern?[ Go to top ]

    As Vincenzo pointed out, DAOs don't allow you switching the persistence mechanism. As ORMs abstract from the database, it makes no sense to abstract from an ORM anyway. Session obtainment and transaction management are better handled by aspects or templates, than handcoded in DAOs. Generic DAOs give you compiletime typesafety, nothing more. DAOs with methods for specific queries are not reusable, because the methods are not exposing intrinsic functionality of something you could call a resuable "DAO component", but implement a bunch of client motivated functionality. Thus, you will probably never have different implementations of a DAO interface. So in the end, what are DAOs for?
  53. Re: Are DAOs an antipattern?[ Go to top ]

    So in the end, what are DAOs for?
    Nothing +1 Guido
  54. Re: Are DAOs an antipattern?[ Go to top ]

    As Vincenzo pointed out, DAOs don't allow you switching the persistence mechanism.
    Sure they do. That's one of the primary roles of a properly designed DAO. The question now is whether a DAO layer is as relevant with the modern ORMs rising in dominance. Since the ORMs are taking much of the brunt of the DB specific SQL handling, a task typically filled by the DAO, then perhaps there is less of a need for the DAO layer. However, the ORMs only work with Relational DBs. Luckily, due to their ubiquity, this isn't really a limitation for most applications. So, the DAOs role was not really to abtract data access, but in fact mostly to abstract the actual SQL used FOR data access. A role the ORMs fill handily. But make no mistake, if you think you can simply drop, say, iBatis and plug Hibernate in to your code without a DAO layer, you're in for a rude shock. Most folks simply don't have that problem, so with the modern tools seperate DAO layers may well be redundant.
    DAOs with methods for specific queries are not reusable, because the methods are not exposing intrinsic functionality of something you could call a resuable "DAO component", but implement a bunch of client motivated functionality. Thus, you will probably never have different implementations of a DAO interface.
    This is a feature, not a bug. DAO layers are custom fit to handle the needs of both sides of the data access equation: the business logic and the persistence logic. They're not supposed to be generic or reusable or anything else. The interface changes with the demands of the business logic, and the internals change with the demands of the persistence logic. The DAO Layer is the glue that binds the business and persistence layers together.
    So in the end, what are DAOs for?
    Isolating logic and persistence from each other. Whether a modern ORM tool can fill the DAO need is an application design question. For many applications, an ORM tool can be used as the DAO layer.
  55. Isolating logic and persistence from each other. Whether a modern ORM tool can fill the DAO need is an application design question. For many applications, an ORM tool can be used as the DAO layer.
    I'm 100% with you.
    This seems to be the only conclusion of this thread.
  56. DAO an antipattern ? Not at all guys !!! Looking not so far, but only at J2EE Blueprints for Data Access Object you can read an important statement:
    Not Useful for Container-Managed Persistence Because the EJB container manages entity beans with container-managed persistence (CMP), the container automatically services all persistent storage access. Applications using container-managed entity beans do not need a DAO layer, since the application server transparently provides this functionality. However, DAOs are still useful when a combination of CMP (for entity beans) and BMP (for session beans, servlets) is required.
    These Blueprints are not still updated for EJB3.0, but we can abstract from this and say that ORM "transparently" solve the problem that DAO solve. Usually I use a "quite-DAO" pattern in my projects (I use Hibernate) only to hide Hibernate internals to my business method, but it's only a matter of taste I think. Again, pattern are good for solving problems only and only if they don't became the problem.
  57. Just like I said... :) http://www.theserverside.com/news/thread.tss?thread_id=40581#209465
  58. DAO, ORM and Spring[ Go to top ]

    I forgot to mention the fact that a DAO pattern is also used into Spring (Spring guys are my real only reference) and in particular we can look at the petclinic example. There the Hibernate implementation of the DAO is done with something that in my opinion is again the pattern: 1) The "load" methods doesn't return detached objects 2) The "save" methods use Session.merge() to update the object without reassociating it to the current Session. But this way they: 1) Don't use transfer objects (please again look at blueprints), but real model object, still attached to the current session. So if for instance I do some set to these object and then I don't do a "save" changes are updated anyway into my relational DB. 2) They must do explicits merge, so loosing the "trasparent" approach of ORM. In conclusion this can be good as an example of how to mix JDBC and ORM, but can be a bad example of how to use Hibernate or ORM in general. What do you think ?
  59. The reality is that sometimes DAOs are the most appropriate way to access a database, sometimes a persistence framework is, sometimes services are, and sometimes it's even best to simply embed SQL code in your business objects. The Agile Data method included the "Sweet Spot" philosophy which captures the idea that it isn't a black and white world, that you need to understand that you have a range of options and therefore should strive to choose the right one. As a result, if you peruse some of the articles at www.agiledata.org you'll see that I often provide several implementation options to address an issue. For example, at http://www.agiledata.org/essays/implementationStrategies.html I overview the four basis strategies to encapsulating database access. The important thing is to understand the trade-offs between the strategies and then apply the right one for your situation. No one "technology size" fits all.
  60. DAO antipattern?[ Go to top ]

    "Isolating logic and persistence from each other. Whether a modern ORM tool can fill the DAO need is an application design question. For many applications, an ORM tool can be used as the DAO layer." Actually, its the other way around. The main purpose of ORM is to map a relational model onto a object model, hence ORM. Data Access Object is to hide the specifics of accessing data stores for filling a object, traditionally a DTO. When a DAO implementation is accessing a relational store, it has to map the data to the Object, which sounds like relational to object mapping. When a new DAOimplementation accesses a CICS store, it dont's. A DAO implementation can therefore be a ORM component. Maybe the DAO adresses objects that can have a variety of stores and ORM is for relational stores. I do think that Business Domain Objects are persisted in a relational stores in 90% of the implementations with no future changes. ORM is the best option for Domain Objects. For configuration Objects which can reside in JNDI, property files, memory, statics, relational/object/xml databases DAO is the way to go. Just my 2 eurocents....
  61. Hi all, Sorry if others have said that before, didn't read the whole thread yet, but I think the "real" solution to this is not to use the DAO-pattern at all - we shouldn't have to deal with persistence explicitely, our "domain objects" should simply be persistent, end of discussion. That's entirely possible with today's technology (as a side note: I think EJB3 is cool but has gone wrong in some parts: there's no reason to give up "datastore-independence" - JDO was much further in some ways, except the QL-capabilities), the only "missing" part is access to the domain objects/entities on the client side, too much code involved in (de/a/rea)ttaching objects. regards, Messi
  62. ...but I think the "real" solution to this is not to use the DAO-pattern at all - we shouldn't have to deal with persistence explicitely, our "domain objects" should simply be persistent, end of discussion.
    Could you explain how this would work?
  63. performance Vs. comfort[ Go to top ]

    I'm surprised that nobody has mentioned performance's view so far. I like ORM approach because I'm a developer and it's fine work with it. But on the other hand there is question how "good" it is for performance, for effeciency? I see ORM suitable for CRUD operations. But sometime you need to read big amount of data only and here I see problem with ORM because it can be never as fast as JDBC. From this reason it's good to use DAO pattern and hide implementation details - use ORM and when needed use JDBC. And I'm again at the beggining of this thread - persistent vs. transient objects. If I want to use JDBC and ORM at once then I can use transient objects only. Customer's satisfaction (=performance) is for me more then developer's comfort. Also I think that this approach is less error-prone - you must explicitly save objects thus you have better control. PETER
  64. Hi! I've been looking for a place to ask this question, but haven't really found any and this thread seems to have plenty of people that have at least opinions about ORM and DAO pattern so... here goes. (please, direct me to a better thread if one already exists) Background: I've been designing a product upgrade for a while that includes joining 2 legacy data sources (one partly exposed with proprietary XML, the other with IDL) into one common web user interface. Also as a requirement is that this new common user interface for legacy datasources would be compatible with new datasource that would eventually replace those 2 legacy ones. I've thought about using Command pattern for getting information from presentation layer to business layer and then DAO pattern (with 3 distinct implementations) to interact with datasources. New datasource would be using Hibernate, which is easy to implement with the generics-example from Hibernate web site (http://hibernate.org/328.html). The other 2 DAO implementations would use same interfaces as in that Hibernate-example, but instead would implement Hibernate specific parts for communicating with XML and IDL respectively. Now, after much testing and trying, it seems to me that it is not easy to have just one set of Commands that would work with both combinations, that is with either 2 legacy DAOs or the new Hibernate DAO. Hibernate uses objects as the combining part between data entities, and the legacy ones are just pure relational. And no, I cant just use Hibernate instead of XML/IDL interfaces, since the legacy systems have validation and other logic that needs to stay in there. So my question is, is the DAO layer the place to have the separation or should also the Commands also be implemented so that they would be aware of what datasource they are actually using? For the web user interface this is a bit problematic, since it would need to be re-compiled when the legacy datasources would be changed to the new one. Then again with good architecture (that is already planned  )this wouldn’t affect more then few classes from the presentation layer. Thanks in advance, and ask for more (or direct me to more appropriate place if you know one) .aRi
  65. Yes, you are obviously missing something. In wrapping the underlying layer as an API (they called it DAO design pattern), you said that converting from JDBC to ORM will render the DAO useless. The thing is that, sometimes we also need to access data bypassing ORM, back using JDBC which is often when getting data for bulk report etcetera. If you bypass the DAO, then the mixed JDB+ORM design will looks ugly. So, so, ugly. Then you might want to add other means of storing data through messaging etc. That'll eventually end up so so ugly. If you just want to implement something yourself, will not be reused, go and fetch directly from ORM. You don't really need strict layering. But if you want to maintain the code for long, integrate with some other things, reusing the data services, then probably you would like to implement it in API, the so-called-DAO-Design-Pattern.
  66. Pros[ Go to top ]

    I am not sure if DAO layer would bring advantages to software developers. As stated, its pattern does not isolate well and might add more concerns. Perhaps it is worth a try. web hosting