[hibernate-dev] [HSEARCH] Autodiscoverable field bridges next steps

Hardy Ferentschik hardy at hibernate.org
Wed Apr 2 07:23:26 EDT 2014


On 1 Jan 2014, at 22:07, Hardy Ferentschik <hardy at hibernate.org> wrote:

> 
> On 1 Jan 2014, at 16:36, Emmanuel Bernard <emmanuel at hibernate.org> wrote:
> 
>> ## Handling duplicates
>> 
>> I had in mind the following logic.
>> 
>> Prevent custom bridge providers to offer bridges in the same situation.

I am still trying to wrap my head around “same situation”. It might help to list the different cases we have. Also the POC
for BridgeProvider has this method:

    FieldBridge returnFieldBridgeIfMatching(Class<?> returnType, AnnotatedElement bridgedElement, String memberName, ServiceManager serviceManager);

1) Explicit field bridge declaration 

@Indexed
class Foo {
    @Field(bridge=@FieldBridge(impl=MyCustomBridge.class)
    String foo;

    @Field
    @FieldBridge(impl=MyOtherCustomBridge.class)
    String snafu;

    // ...
}

These is the simple case. BridgeProvider is not even involved, since the bridge is explicitly specified

2) Bridge is indirectly specified via its context 

2a) @TikaBridge

@Indexed
class Foo {
	@Lob
	@Basic(fetch = FetchType.LAZY)
	@Field
	@TikaBridge
	Blob content;

        //...
}

2b) @Spatial

@Indexed
class Bar {
	@Spatial
	public Coordinates getLocation() {
		return new Coordinates() {
			@Override
			public Double getLatitude() {
				return latitude;
			}

			@Override
			public Double getLongitude() {
				return longitude;
			}
		};
	}
}

2c) Some custom annotation 

@Indexed
class Foo {
    @Field
    String foo;

    @Field
    @Snafu
    String snafu;

    // …
}

A couple of considerations here. I guess 2a and 2b are the driving force behind passing the AnnotatedElement into the BridgeProvider contract. The current implementations would check whether 
an annotation like @TikaBridge or @Spatal exist and behave accordingly. Part of the problem is that in the case of programmatic configuration we now have to create a pseudo annotated element 
to make this contract work (see related discussion). This works fine with the current commons-annotations approach, but the aim is really to let the programmatic configuration populate the internal
metamodel directly instead of creating pseudo annotations. 

The question for me atm, is why we go via the BridgeProvider at all for 2a and 2b? The bridge might not be explicitly specified via a @Bridge annotation, but it is still a clear case due to
@TikaBridge and @Spatial. Why can not the AnnotationMetadataProvider take care of this and during the processing of the annotations of a property act accordingly. A programmatic metadata provider 
would also just act depending on whether spatial() was specified or not.

The problem maybe starts already at BridgeFactory#guessType which gets also passed (numeric) field  annotations as well as the processed member. guessType does then two things, it processes the 
annotations and if potentially queries the BridgeProviders. I think parts of the responsibility should be moved into AnnotationMetadataProvider. BridgeFactory#guessType should really only be called in
the case where the bridge is not explicitly or implicitly specified.

Which leaves 2c. The question is whether we think it is a valid use case to have a BridgeProvider which returns a different bridge depending on some non Search related annotation (@Snafu). If so,
we indeed need to pass the AnnotatedElement into the BridgeProvider.

3) No explicit or implicit bridge config

@Indexed
class Foo {
    @Field
    String snafu;

    // …
}

I guess this is main use case for the BridgeProvider, right? In this case the bridge really depends on the type of the indexed property (in the worst case also on some additional custom annotation if
we support 2c).


Thoughts?

—Hardy 




More information about the hibernate-dev mailing list