Werner Punz wrote:
Richard Wallace wrote:
How do you normally do search functionality like this?  Do you expose
the Hibernate query API to the JSF layer?
No, that is why the BO-DAO Pattern existis, I usually
and that works exceptionally well, split the application
into three layers
one which is tied to JSF sort of the UI layer then the business object
layer which encapsules all the functionality needed in a semi/reusable
abstracted business layer and over that layer automated transactions
are woven via aop (spring in the last two cases)
and the pure database access is moved into DAO objects.

It is more overhead to program, but in the end you get resuable business logic
and a rather good abstraction of the data access layer.

In the long run probably a move of the BO layer to EJB3 will make sense
(I am using Spring for that now)
but EJB was sort of a no touch thing to me, up until recently, due to the 
overhead
complexity and glue code involved with it, that will change soon with EJB3.

Yes, this is the EXACT situation I'm in. I have my DAOs only doing data access and have a BO, or "service" layer, that is where I do all the more complicated business logic stuff and JSF only ever accesses the service API. I also use Spring and have my transactions woven in with aop and plan to also use acegi to weave in authorization.
The main reason I wanted to try and abstract it was in case we did see
some need in the future to swtich to a different ORM tool like EJB 3 or
whatever else is the latest greatest.  I mean, in theory, the
presentation layer shouldn't care one wit what the data access layer
uses to get it's job done.  That's the whole reason for abstracting the
Hibernate stuff in DAOs.
I think DAO should be enough, you just pass the parameter lists
you determine into the DAO and have the query logic there
figure it out.
No need for another layer of query abstraction,
you might also consider to move all your query stuff which is not
categorized to a central place so that you can adjust that.
But moving that stuff into a DAO layer if you do it cleanly should
be sufficient to give you the chance to move the
data access into another system, one of the reasons why
the DAO pattern exists at all.

The only reason I'm reluctant to do something like a parameter list is because it's pretty limited to the kind of queries you can do. Usually you'll be stuck only doing an and or an or on all the parameters and can't really do anything more complex. For most situations that would be ok but there are a couple of situations in which I will need to be able to do more expressive queries.
I don't think my situation is all that different from others that are
out there.  I have Hibernate at the lowest level doing data access,
spring in the middle managing services which use the data access layer
and then JSF at the presentation layer utilizing the APIs the services
expose.  I guess I'm just curious about what the best practices are and
what people would think if I exposed the fact that the data layer is
using Hibernate at the presentation layer by using the Hibernate
criteria API.

No as I said... push the query data through your layers
as POJOs into the DAO layer and have the dao layer deal with it on the query 
level.
But do not push controls or something else JSF related into either the Business 
Layer
or the DAO layer, you lose portability and and up in a mess which is hard to 
clean
afterwards.

Generally following the DAO-BO approach with a clean separation of concerns
is currently to my knowledge considered a very good approach. You get other 
benefits
from it, like you can AOP the interfaces and do other stuff (like adding 
automated transaction
handling on business level, you can do a simulation on parts of the system
which are not finished and then IoC the parts you just get in etc...)

The downside of this pattern is, it is rather
coding intensive and definitely not suitable for
quick hacks and swiftly written applications.
The ideal idea would be to have a collection of
business objects which you can apply to a workflow
the system has to perform, but that idea is unfortunately good on paper
but does not work out as expected in reality. Hence the whole EJB approach
sort of was a good idea but did not work fully out.

Alright, it sounds like there are a couple of approaches that I can explore. 1) Passing a list of parameters to the DAOs and let them build the criteria or query to be executed. One interesting thing here is that I could actually use some query by example kind of thing and then just use Hibernates query by example capabilities. Otherwise, this is probably going to be something like a list of some kind of object that encapsulates the property, the operation and the value to do the filtering with. This would limit me to doing only disjunctions and conjunctions, but it does put all the data access specific logic in the DAOs where they should be.

2) Expose a Search component that is specific to the underlying data access method being used. This would be separate from all the other service and DAO components. Then a set of search functionality in JSF would just use that Search component to do whatever it needs. In the case of a Hibernate search component it would need to pass DetachedCriteria. This probably isn't the cleanest solution but it is probably the most flexible and it does centralize where changes need to be made in order to perform searches. One plus is that this Search component would be easy to use across projects.

I think I'm going to try out the 2nd approach first because it does give me the most flexibility and will be the quickest to implement. What do you think?

Thanks for all the input Werner, I really appreciate it,
Rich

Reply via email to