tags:

views:

285

answers:

1

I have a hibernate filter that needs to evaluate using two different columns in the database. I have another existing hibernate object that contains both of those fields, and I would like to be able to pass the other hibernate object into the session.enableFilter.setParameter() call, rather than pass both the values contained in it separately.

Specifically, I would like to replace this code:

session
     .enableFilter("inLocation")
     .setParameter("traversalLeft", 5)
     .setParameter("traversalRight", 10);

with this code:

session
     .enableFilter("inLocation")
     .setParameter("location", locationHibernateObject)

to better insulate excactly what the filter needs.

But when I try to configure the filter like:

@FilterDef(name="inLocation", parameters=@ParamDef( name="location", type="com.example.Location" ) )
@Filters( {
    @Filter(name="inLocation", condition="current_location_id in (select location.id from location where location.traversal_left between :location.traversalLeft+1 and :location.traversalRight)")
} )
public class ClassToFilter {

I get an error trying to call enableFilter()

Is this something that is even possible? What am I doing wrong?

A: 

I have encountered the same problem it seems.

I am using hibernate-annotations-3.4.0.GA, and my filters and custom types are in one package-info.java file. With that setup, the problem seems to be in:

  • org.hibernate.cfg.AnnotationBinder#bindPackage(), where filters are being processed before, rather then after custom types.
  • org.hibernate.cfg.AnnotationBinder#bindFilterDef(), that does not try to discover the custom types at all.

I changed the calling order of methods, and replaced the call in bindFilterDef() with:

    private static void bindFilterDef(FilterDef defAnn, ExtendedMappings mappings) {
        Map params = new HashMap();
        for (ParamDef param : defAnn.parameters()) {
            ///////////////////////////////////////////////////////////////////////////////////////////////////////////
            // support for custom types in filters
            params.put( param.name(), getType( param.type(), mappings ) );
        }
        FilterDefinition def = new FilterDefinition( defAnn.name(), defAnn.defaultCondition(), params );
        log.info( "Binding filter definition: {}", def.getFilterName() );
        mappings.addFilterDefinition( def );
    }

    ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    // support for custom types in filters
    private static org.hibernate.type.Type getType(String paramType, ExtendedMappings mappings) {
        org.hibernate.type.Type heuristicType = TypeFactory.heuristicType( paramType );
        if ( heuristicType == null ) {
            org.hibernate.mapping.TypeDef typeDef = mappings.getTypeDef(paramType);
            if ( typeDef != null ) {
                heuristicType = TypeFactory.heuristicType( typeDef.getTypeClass(), typeDef.getParameters() );
            }
        }
        log.debug( "for param type: {} parameter heuristic type : {}", paramType, heuristicType );
        return heuristicType;
    }

Of course, then I had to build the jar from scratch, but the change seems to solve the problem.

However, in Hibernate 3.5, annotation classes are bundled inside hibernate3.jar, so more work could be required, since everything has to be built from scratch.

javashlook
That definitely makes it sound like a hibernate problem, and not just a configuration I was missing.
Nathan Voxland