Hibernate container and searching

Hi forum,

I’m using a hibernate container, and I want to implement search in it.

I need to have fairly involved tests, not just a string comparison test. It looks like the filter interface in container is too simple for me, but I’m not entirely sure.

Is there a simple way to do this? If not, could someone give a couple of pointers to implementing it?

The way I would really love for this to work is to have a filter object between my container and my table. This filter object will then implement the tests to say if a row is acceptable or not.

Thanks,

Bo Thorsen,
Monty Program AB.

Hi!

I have found the Filterable api in Vaadin a bit limeted in some cases too. An option is to forget that api and limit the query with Hibernates Criterias. The problem with this approach is that HbnContainer does support this yet. However it should be quite easy to modify to support this and the “official” solution is actually on its way as Jeppe Cramon is preparing a patch that allows developer to modify the base criteria HbnContainer uses to list items. See thread: http://vaadin.com/forum/-/message_boards/message/40393#_19_message_36075

cheers,
matti

I had a look at the HbnContainer implementation in svn right now. It does have some hibernate filtering implemented, but I’m not sure if it’s enough.

Here’s a longer explanation of what I’m trying to do:

I have a list of persons or companies who each has some skills. These skills can be rated from 1 (newbie) to 5 (expert). Each person also has a list of properties - address, phone number etc.

I’d like to have a single text field where a user can write any text, and the search will accept all rows that has the text in any of the text properties of a person.

I also want to be able to say that I am searching for persons who has skills C++ with minimum 3 and SQL with minimum 4.

In a manually controlled database, I’d add a search view that concats all text fields of the row, and search that one. And make a simple search on all the skills with the minimum level.

I can’t see how a search like this can be implemented with HbnContainer.

I’m right now attempting to build a filter that sits between the container and the table, but this is also very difficult.

Bo.

I think the solution for now is to just subclass the HbnContainer and add a method I can override to add the criteria manually. The Hibernate criteria should be able to do all the necessary searches.

Or I’ll just fork HbnContainer for now and add the code directly.

Bo.

Hi!

Sorry, I had a critical typo in my post which probably got you confused. I forgot “not” from “The problem with this approach is that HbnContainer does support this yet.” But you got it right anyway. If you are busy and cannot wait for Jeppe’s additions I suggest you modify the HbnContainer class directly. Just making getBaseCriteria protected (and then extend for distinct use cases) might be enough.

matti

My solution is possibly one you could add to the code, because it allows complete customization.

I have added this method at the end of the HbnContainer class:

/**
 * This is a template method subclasses can override to add more criteria for hibernate.
 * 
 * The default implementation does nothing.
 * 
 * @param criteria The base criteria as this class implements it with the Filterable search.
 * @return The new search criteria, possibly modified with extra restrictions or replaced completely.
 */
protected Criteria addSearchCriteria(Criteria criteria) {
	// No modification necessary in this class. It is only for the subclasses to use.
	return criteria;
}

And I have added a call to this method in getBaseCriteria():

private Criteria getBaseCriteria() {
	Criteria criteria = sessionManager.getSession().createCriteria(type);
	if (filters != null) {
		for (ContainerFilter filter : filters) {
			String filterPropertyName = filter.propertyId.toString();
			if (propertyInEmbeddedKey(filterPropertyName)) {
				String idName = getClassMetadata().getIdentifierPropertyName();
				filterPropertyName = idName + "." + filterPropertyName;
			}

			if (filter.ignoreCase) {
				criteria = criteria.add(Restrictions.ilike(filterPropertyName, filter.filterString, filter.onlyMatchPrefix ? MatchMode.START : MatchMode.ANYWHERE));
			} else {
				criteria = criteria.add(Restrictions.like(filterPropertyName, filter.filterString, filter.onlyMatchPrefix ? MatchMode.START : MatchMode.ANYWHERE));
			}
		}
	}

	// Allow subclasses to modify the criteria
	criteria = addSearchCriteria(criteria);

	return criteria;
}

With this, I don’t change any substantial amount of code in HbnContainer, and I still allow for complete customization of the search criteria.

I also made the methods clearInternalCache() and fireItemSetChange() protected, so the subclass can tell when the search criteria changes so the visible entries might have changed.

I hope you will be interested in adding this code to HbnContainer. It might not be as good as a full built-in search system, but it does the job and doesn’t limit the class users.

Bo.

Any idea if these additions could happen soon?

Hi!

Current version in svn contains the changes already.

http://dev.vaadin.com/browser/incubator/hbncontainer/src/com/vaadin/data/hbnutil

cheers,
matti

Great thanks. Works like a charm.