4

I am working on a CRM project that uses Spring MVC and Hibernate and I do not know what is the best place to use hibernate criteria. I want to use hibernate criteria because we have search capability on our presentation layer and users can search based on lots of various parameters in different ways. Sometimes we just need IDs, sometimes we need a subset of properties, sometimes we need to join multi tables, etc. So, building a structured criteria like hibernate's criteria instead of passing a list of parameters, orders, required parameters and search limits from presentation layer to data layer, can clean up the code. However, I know it is not correct to use hibernate in presentation layer as it is against MVC architecture. And I really don't think duplicating hibernate's criteria is the correct approach. I could think of 3 approaches:

  1. Creating a dozen methods in business layer, one for each type of search requests, and calling each of these functions from presentation layer based on the situation. Each of these methods basically, do not do anything but passing the parameters to a corresponding DAO method which would create a SQL query (or criteria object) and retrieves the data from database. In this approach I would end up with hundreds of methods which do not do anything but passing the parameters to the DAO.

  2. Creating a Class similar to Hibernate's Criteria class in presentation (or business layer). Then initiating this object with search parameters in presentation layer and passing it to DAO. DAO then creates a hibernate's criteria object based on this object. This approach involves duplicating hibernate's criteria class.

  3. Initiating Hibernate's Criteria class in presentation layer and passing it to DAO to get the search result.

Can you please let me know which one is the best approach?

Thanks

Babak
  • 41
  • 2

3 Answers3

1

I think the best choice depends on your query requirements.

If possible, I would recommend you to go for the first alternative. I often find myself implementing DAO search methods that take a lot of nullable parameters. The DAO method itself builds the criteria object adding constraints if the corresponding method parameters are not set to NULL.

This is a simple example:

public List<SomeObject> findSomeObjects(String name, Integer categoryId, 
      Date dateTimeFrom, Date dateTimeUntil) {
   if (name != null)
     // add name to criteria
   if (categoryId != null)
     // add category to criteria
   // ...
}

If there really are a lot of different search operations and the number of combinations is very high, you might also try your second alternative. Maybe you can restrict your Criteria "clone" by simplifying and tailoring it for your use cases.

Matthias Wuttke
  • 1,982
  • 2
  • 21
  • 38
  • Thanks Matthias for your answer. The first approach is what I started doing last year and I ended up with lots of large and complicated methods in DAO because we need various table joins and projections (restrictions on which columns needs to be loaded) in addition to the huge number of search parameters. So, I picked the second approach after awhile and built my own Criteria class and started expanding it and duplicated most of hibernate's criteria functionality. So, I was wondering what is the common approach. And maybe using Hibernate's Criteria in presentation layer is not a bad idea. – Babak Oct 04 '11 at 02:26
1

Another option is to create a query-specific layer. This concept comes from CQRS. I don't use NHibernate but I do use ADO.NET to perform my queries directly since I subscribe to the idea that the domain model should not be queried. Nothing wrong with loading a full aggregate here-and-there but definitely not for ad-hoc querying.

So, hypothetically, you could have something like ContactQuery with methods such as:

  • public string Name(Guid contactId)
  • public DataRow Details(Guid contactId)
  • public DataTable CustomerContacts(Guid customerId)

In this way your queries are abstracted. Hopefully NHibernate projections return DataRow / DataTable :)

Eben Roux
  • 12,983
  • 2
  • 27
  • 48
0

I would go with creating and passing Criteria objects onwards to the DAO layer. The reason is twofold:

  1. to prevent natural explosion of finder methods in DAOs
  2. to avoid code duplication (which is inherent in the second option).

Thus you may treat criteria objects as a part of the vertical domain layer.

P.S. I don't know your situation, but a slightly better option might be using JPA 2 Criteria as a standard "alternative" to Hibernate Criteria just to avoid dependency on Hibernate-specific features without a strong necessity.

Dmitri
  • 93
  • 1
  • 5