Originally posted by David Harkness:
This was just discussed one or two weeks ago either in this forum or one of the Java in General ones -- probably this one I'd hope. Actually, I assume you're talking about using static methods instead of a DAO instance, correct?
The main problem with this is that you can't ever swap out your DAO for something else: either a different implementation or a mock object for testing. You're much better off creating an interface and implementation. Go ahead and use a singleton instance of the DAO; tools like the Spring Framework make this a snap. Check out the ORM forum for recent discussions on using Spring for this.
Static methods should be reserved for things that won't ever change. While it's conceivable that you may want to swap out a different implementation of the java.util.Math methods, it's pretty unlikely. But to test a business object that uses a DAO, it is much nicer to use a mock DAO (jMock or EasyMock; I slightly prefer the former) so you can test the business object in isolation (this is the whole point of unit testing).
If you use static methods, all your tests have to run against a real database or you need to swap in a different JAR with a different class that has the same static methods. Ouch!
So turn it around: what specific reasons do you have for using static methods? What do they buy you? Maybe we can give you other ways to get the same benefits without them.
Originally posted by David Harkness:
I certainly didn't mean to imply there aren't valid reasons. I'm not badgering the witness, honestly!![]()
Now that I'm using Spring I no longer use the Singleton pattern in the following form, but my DAOs are effectively singletons. All of the business objects that use the DAOs reference a single instance, but that doesn't preclude having multiple instances for different BOs or instiating a new one for each request (Spring supports this model too). But if you're not using a similar framework, the old standby Singleton pattern works pretty well.A common anti-pattern is to have the factory create the DAO in the inst() method if it hasn't been created yet, but then you're limiting yourself to a single implementation (though you could have it instantiate the default implementation I suppose). Instead, you'll need to bootstrap your DAOs in a startup servlet or some other way.
To use it is nearly as easy as static methods:You can of course make the instance available in a context object or anywhere else you like from there.
No problem, glad to help!Originally posted by Gregg Bolinger:
Question, in the UserDaoFactory, when/how does getInst get called so that the instance is created? Instead, you'll need to bootstrap your DAOs in a startup servlet or some other way. If this is the answer, could you explain that a bit more? Thanks.
I don't understand this statement. What does one have to do with another? Are you thinking that the framework would obviate the need for DAOs, that it has its own DAOs so you won't learn about making your own? I can say that that isn't the case. I had to write my own DAOs.Originally posted by Gregg Bolinger:
I am not going to use Spring. I've been wanting to understand DAO's and using a framework won't help me.
Heh, now I'd absolutely recommend Spring! Hibernate is tough enough, Spring would help you a lot by doing a lot of the grunt-work. But I'll put that aside for now.However, I have done enough JDBC and SQL to last me a lifetime so I am using Hibernate. Does anyting you suggested change with regards to the above statement?
If you are in a CMT environment, you should no longer need Spring. AFAICT, people use spring here for four things:
(1) session handling/flushing
(2) transaction management
(3) SQLException mapping
(4) Runtime exceptions model
Well, with hibernate.transaction.flush_before_completion and hibernate.transaction.auto_close_session, (1) is now much, much easier. (2) is handled by CMT. (3) is implemented in the Hibernate Dialect. And Hibernate3 has an unchecked exception model, so (4) is no longer relevant.
I do admit that this is an issue going forward as I am dependent on the Spring team continuing to update Spring as Hibernate releases new features.I'm currently working on a project with Spring + hibernate 3. I started with Hibernate 2.1 but had too many issues with collections and composite keys so I switched to Hibernate 3 and everything worked out of the box.
There are two places where it helps. The first is if you ever need different implementations of your DAOs -- say you migrate to the next cool persistence layer. Now you must go through all your code and change "new HibernateUserDAO()" with "new CoolBeansUserDAO()". Granted, with grep this isn't that big of a deal, except that you can't do it at runtime. You must maintain two codebases, one for each DAO implementation.Originally posted by Gregg Bolinger:
So what advantage does the suggested UserDAOFactory have? How does it help me?
My book, my movies, my videos, my podcasts, my events ... the big collection of paul wheaton stuff!
In my case, since some domain objects contain Collections (Sets actually) of related entities and aggregates, my DAOs don't have a one-to-one mapping to tables, but I still think either name is applicable. Whether it maps to one or multiple tables, it still provides access to the underlying data source.Originally posted by Paul Wheaton:
I prefer TG: Martin Fowler's "Table Gateway Pattern". This is the DAO with the one-to-one mapping.
Keep in mind that objects provide both state and behavior. Objects without state may still need to have their behavior overridden. Besides, the DAO does end up having state: a Hibernate SessionFactory.Unlike Mr. Harkness, I prefer to use static methods for anything that does not make for an object (no state means no object).
That's pretty cool. Am I correct that mocking requires CGLIB (in-place alteration of existing classes) due to the use of an inner class? Not a real problem as CGLIB is quite mature, but some people still have an aversion to it for various reasons.My solution is that a class provides static methods, but those methods will call an instance of an inner class called "Implementation".
My book, my movies, my videos, my podcasts, my events ... the big collection of paul wheaton stuff!
Can it use multiple data sources for the same DAO at the same time? I don't mean a DAO that uses two data sources to do its work, I mean two of the same DAOs (UserDAO) that point to do different data sources. For example, how would a tool that copies users from one database to another use the singleton UserDAO against two DSes?Originally posted by Paul Wheaton:
Jenny uses multiple data sources.
My bad, it often comes up when discussing mock objects, so I assumed you were familiar with it. CGLIB is a tool to modify class files at runtime. It is used frequently when you need to replace (with a mock) or augment (with AOP) a class instead of interface. When you have an interface, you can just generate a class that implements it, but when you have a class, you need to alter it in-place.Sorry, I don't know what CGLIB is.
Cool, that pretty much answers it for me.Jenny generates everything you need. Jenny essentially generates what many people call a "DAO".
Don't destroy the earth! That's where I keep all my stuff! Including this tiny ad:
Smokeless wood heat with a rocket mass heater
https://woodheat.net
|