[hibernate-dev] Hibernate Search Metadata API: Numeric and other special Field types in Hibernate Search

Emmanuel Bernard emmanuel at hibernate.org
Tue Jul 16 04:41:19 EDT 2013


Like gunnar, I was thinking that a type property and an unwrapping
method would do the trick. Though I'd favor delegation over
subclassing.


On Tue 2013-07-16  9:27, Gunnar Morling wrote:
> Hi,
> 
> > I won't mention my favorite Vattern. I've considered adding subtypes
> but not liking it as their usage would not be clear from the API.
> 
> How would you use your vavorite Vattern without subtypes? And which other
> option would you prefer then?
> 
> I think the field-type specific information can either be on
> 
> a) FieldSettingsDescriptor itself (as is today)
> b) specific subtypes of FSD
> c) specific delegates of FSD, safely accessible via a type parameter of FSD
> 
> a) would IMO be the simplest but could lead to a proliferation of
> attributes on FSD; So as you say it depends on the number of specific
> attributes whether its feasible or not. But even if sticking to this
> approach, we might consider to replace boolean isNumeric() with FieldType
> getFieldType(). This would avoid adding a new isXy() method for each
> specific type and be used like so:
> 
>     if ( desc.fieldType = NUMERIC) {
>         doSomething( desc.precisionStep() );
>     else if ( desc.fieldType = FOO ) {
>         doSomething( desc.fooAttrib() );
>     }
> 
> For b), you need a way to narrow down to the subtype, either via Visitor or
> some kind of cast. I still find this pattern as used in BV reads quite
> nicely:
> 
>     Object result = null;
>     if ( desc.fieldType = NUMERIC) {
>         result = doSomething( desc.as( NumericDescriptor.class).precisionStep()
> );
>     else if ( desc.fieldType = FOO ) {
>         result doSomething( desc.as( FooDescriptor.class).fooAttrib() );
>     }
> 
> In particular, as() would only accept subtypes of Descriptor and be thus a
> bit safer than a plain downcast.
> 
> Btw., the annotation processing API (as e.g. used by the Meta model
> generator or the AP in Hibernate Validator), offers both ways for that
> purpose, i.e. a visitor approach and, getKind()  + downcast. Having worked
> with both, I find the usually simpler to use.
> 
> For a comparison, the last example would look like this with a visitor
> design similar to the annotation processing API (the type parameters are
> for parameter and return type passed to/retrieved from the visitor):
> 
>     Object result = desc.accept(
>         new FieldDescriptorVisitor<Void, Object>() {
> 
>             @Override
>             Object visitAsNumber(NumberDescriptor descriptor, Void p) {
>                 return doSomething( descriptor.precisionStep() );
>             }
> 
>             @Override
>             Object visitAsFoo(FooDescriptor descriptor, Void p) {
>                 return doSomething( descriptor.fooAttrib() );
>             }
>         }
>     );
> 
> Personally, I find this reads and writes not as nice as the other approach.
> 
> Regarding c), one could think of something like this:
> 
>     class FieldSettingsDescriptor<T extends DescriptorSpecifics> {
>         public T getSpecifics();
>         ...
>     }
> 
> and
> 
>     FieldSettingsDescriptor<NumberSpecifics> numberDescriptor = ...;
>     doSomething( numberDescriptor.getSpecifics().precisionStep() );
> 
> But the question is how one would obtain a properly typed descriptor. E.g.
> from a collection with mixed fields, one would only get
> FieldSettingsDescriptor<?>, making this quite pointless.
> 
> I think, I'd like the getType()/as() approach best. Or do you have yet
> another approach in mind?
> 
> --Gunnar
> 
> 
> 
> 2013/7/15 Sanne Grinovero <sanne at hibernate.org>
> 
> > The new FieldSettingsDescriptor [1] has a couple of methods meant for
> > Numeric fields:
> >
> >  /**
> >  * @return the numeric precision step in case this field is indexed as
> > a numeric value. If the field is not numeric
> >  *         {@code null} is returned.
> >  */
> >  Integer precisionStep();
> >
> >  /**
> >  * @return {@code true} if this field is indexed as numeric field,
> > {@code false} otherwise
> >  *
> >  * @see #precisionStep()
> >  */
> >  boolean isNumeric();
> >
> > Today we have specific support for the
> > org.apache.lucene.document.NumericField type from Lucene, so these are
> > reasonable (and needed to build queries) but this specific kind is
> > being replaced by a more general purpose encoding so that you don't
> > have "just" NumericField but can have a wide range of special fields.
> >
> > So today for simplicity it would make sense to expose these methods
> > directly on the FieldSettingsDescriptor as it makes sense for our
> > users, but then also the #isNumeric() is needed as not all fields are
> > numeric: we're having these extra methods to accommodate for the needs
> > of some special cases.
> >
> > Considering that we might get more "special cases" with Lucene4, and
> > that probably they will have different options, would we be able to
> > both decouple from these specific options and also expose the needed
> > precisionStep ?
> >
> > I won't mention my favorite Vattern. I've considered adding subtypes
> > but not liking it as their usage would not be clear from the API.
> >
> > Cheers,
> > Sanne
> >
> > 1 - as merged two minutes ago
> > _______________________________________________
> > hibernate-dev mailing list
> > hibernate-dev at lists.jboss.org
> > https://lists.jboss.org/mailman/listinfo/hibernate-dev
> >
> _______________________________________________
> hibernate-dev mailing list
> hibernate-dev at lists.jboss.org
> https://lists.jboss.org/mailman/listinfo/hibernate-dev


More information about the hibernate-dev mailing list