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

Emmanuel Bernard emmanuel at hibernate.org
Wed Apr 2 11:37:42 EDT 2014


Yes your analysis is correct.
I would clarify that 3 or 2c don’t have to apply on already supported return types, it is more likely custom types like JodaTime types.

I do think 3 is the most valuable but that 2c is a relatively close second.

Now the @Spatial and @TikaBridge annotations do have attributes which will influence how the underlying bridge is created.
I don’t think you are proposing to move the spatial and Tika bridge creation up on AnnotationMetadataProvider. That would AFAIU duplicate the bridge creation logic between the AMP and some ProgrammaticMetadataProvider.
Also I have a hard time navigating and understanding AnnotationMetadataProvider, so I’m not sure we should make it more complex.

So somehow, the AMP should convert @Spatial, @NumericField, @TikaBridge, and @DateBridge into some non annotation based representation and pass that information to the bridgeFactory. Your approach would be to call explicitly buildXxxBridge() - like buildDateBridge() - methods form AMP. These would be hosted on the BridgeFactory. Is that correct? And the same explicit call logic would be done on a programmatic API equivalent.

Now how would you pass and to these kind of explicit calls in the 2c case when the annotation is unknown a priori?

On 02 Apr 2014, at 13:23, Hardy Ferentschik <hardy at hibernate.org> wrote:

> 
> 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