On 2 April 2014 22:20, Emmanuel Bernard <emmanuel(a)hibernate.org> wrote:
Please everyone and especially Sanne, read this branch of the
exchange Hardy and I have. We need another pair of eyes to make sure we don’t mess things
up as it is an important departure compared to how things are done today (and in my
I've been quiet but not ignoring :) Many interesting ideas in this
thread which need settling.
Hardy, I am starting to come along your side on this discussion. They
key things that made me swing is that if a user needs a special annotation to customize
the bridge, then it’s equivalent to a @FieldBridge. So a feature like CDI stereotypes or
BV’s composition (by annotating a custom annotation with a @FieldBridge) would solve that
problem more elegantly.
I am still a bit sceptical to move the bridge discovery to AMP - at least when explicit
annotations are at play because:
- AMP is complex
- BridgeFactory seems a nice focal point to everything bridge related
- a few common rules must be applied to bridges (like the IterableBridges / MapBridges
and ArrayBridges wrappers)
Nevertheless the idea of inferring types via @FieldBridge, @TikeBridge, @DateBridge,
@Spatial in a separate method than guessType has merits.
Yes I agree about the split, and the stereotypes idea is fascinating.
In fact let's highlight that @Tika and @Spatial are fundamentally different:
isn't just a bridge, it marks an attribute for very special handling
which goes far beyond the transformation into an indexable
representation, so yes this needs to be treated differently.
this one is indeed just a "bridge on steroids" with some added sugar
to pass it the parameters in a more explicit way than usafe of
So @Spatial isn't something we can change too much (unless I've missed
a concrete proposal), but the @TikaBridge seems like a nice candidate
to retrofit into a stereotype model. That way, the @TikaBridge
annotation could be packaged in the Tika extension in its separate
In fact, the stereotype subject came up before:
Even beyond this, maybe considering @TikaBridge as an example for this
feature was a terrible mistake I made: the issue at hand is about
providing a default Bridge implementation for well known *types*, but
Tika applies to Blobs and byte arrays! That should really not be a
binding rule without an explicit annotation. Let me amend about that
and just say that implementing extensions like we did with Tika should
be easier for an integrator, so for this one stereotypes really sound
a better path.
In practice for Date related add-ons like JodaTime and Java 8 date, I am wondering if we
should ensure that someone can use @DateBridge. After all a resolution is likely
conceptually needed and forcing another annotation seems wrong.
Great point. I agree the same annotation would seem a natural fit for
the other time types.
Usually though we need DateBridge because we need to represent the
desired precision, while in JodaTime (and in Java8) the precision of
the type is represented by specific types. For example
org.joda.time.LocalTime doesn't have the date, it just provides time
of day information (and has no timezone either);
maybe the user doesn't need the milliseconds precision, so that might
be a reason to still need use
As otherwise there would be no point in using @DateBridge.
So let's assume that @DateBridge is still needed, and needs to be
compatible with all these; I suspect it could not be retrofitted into
a stereotype annotation, because it would be unclear which extension
module among these time systems should "own" the annotation.
However if we make a specific bridge for each of these types, which
gets automatically in play because of coupling to the type of an
indexed property, and we could consider the @DateBridge annotation as
a DTO for parameters to whatever the actual FieldBridge
We could generalize this concept by meta-annotating the @DateBridge
and @CalendarBridge annotations with something like
@ParameterToFieldBridge : any user annotation on a field with such an
annotation, is passed to the registered FieldBridge for that type.
A nice additional consequence would be to retrofit @NumericField into
the same model: its primary purpose is to carry the precision and
format options to the backing bridge implementation.
To resume the attack to the Tika problem: the @TikaBridge annotation
could be both binding the bridge implementation to the property, and
be the @ParameterToFieldBridge to hold parameters to the bridge
Likewise for "Hibernate Spatial” types, it will probably make
sense to support them as annotated with @Spatial like we do for Coordinates.
Yes we could do that, as long as the indexed type represents a Point
and not a complex shape. But Spatial is a special case anyway and I
don't think we can generalize here to retrofit it into a stereotype
So what do we do about there?
- are they legit use cases (I think they are)
- is that supposed to be supported by some other features unrelated
I lost the subject :)
- should we design BridgeProvider in a way that let them react to
these built in annotations? (via explicit methods I suppose).
Spatial is special, so probably needs explicit handling. All others
might be handled with a combination of @ParameterToFieldBridge (or
whatever better name you all will agree on) and a BridgeProvider
accepting the respective type. Conceptually this means you'd be able
to provide a custom function (code) and a way to get any parameters
passed to it: no limit to creativity :)
Unrelated to the discussion, but to fuel the brainstorming on nice use
cases: custom Hibernate types, Money, @ElementCollection. Probably
even an Embeddable Component could be indexed via a bridge coupled to
its type as an alternative strategy to @IndexedEmbedded.
PS: I’ve spend around 20hrs on that feature so if we could converge, that would be good
On 02 Apr 2014, at 21:18, Hardy Ferentschik <hardy(a)hibernate.org> wrote:
> On 2 Jan 2014, at 17:37, Emmanuel Bernard <emmanuel(a)hibernate.org> wrote:
>> Yes your analysis is correct.
> Cool, so we seem to be on the same page then.
>> I do think 3 is the most valuable but that 2c is a relatively close second.
> +1 for case #3 being the most important one. I would even go so far to say that this
is the only one we should address with the BridgeProvider.
>> 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
> That’s what I am proposing. Also the processing of the @Bridge annotation (standalone
or as part of @Field) should move. Really
> what happens in BridgeFactory#findExplicitFieldBridge (which is funny enough called
by something like BridgeFactory#guessType)
> is annotation and hence AnnotationMetadataProvider specific. BridgeFactory#guessType
could really just become the handler of the described scenario 3.
>> That would AFAIU duplicate the bridge creation logic between the AMP and some
> No, not really or at most temporarily. Remember, using commons annotations and pseudo
annotations are just a crutch. It would be much easier to
> instantiate the right metadata and bridges directly. After all the user does
explicitly something like .property( "name", ElementType.FIELD ).spatial()
> There is not need to guess, you could create the appropriate bridge directly.
>> Also I have a hard time navigating and understanding AnnotationMetadataProvider,
so I’m not sure we should make it more complex.
> Sure AnnotationMetadataProvider is a lot of code, but it is actually still very
similar to the code you originally wrote for DocumentBuilder. It just has moved.
> An indexed class is processed by creating the class hierarchy for this class and then
iterating the class hierarchy finding indexed properties. You should
> be able to follow the flow quite easily from
AnnotationMetadataProvider#initializeClass. Also have a look at the call sites for
>> So somehow, the AMP should convert @Spatial, @NumericField, @TikaBridge, and
@DateBridge into some non annotation based representation and pass that information to the
> Somehow you would create the bridge directly. Either from the
AnnotationMetadataProvider or we need some additional methods on BridgeFactory.
>> Your approach would be to call explicitly buildXxxBridge() - like
buildDateBridge() - methods form AMP.
> That would be one way of doing it. If these methods would be in BridgeFactory they
could even be called from the programmatic config
>> 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?
> A couple of things here. buildXxxBridge() are specific to our internal bridges
(date, spatial, tika). There is no equivalent for custom (user provided) bridges. They are
> explicitly configured or go via the BridgeProvider contract. If we truly want to
support 2c, we need something like the AnnoatedElement in the contract of BridgeProvider.
> On the other hand, 2c can also be solved by the user by specifying his bridge
> If we just think about case #3 BridgeProvider could almost become:
> FieldBridge returnFieldBridgeIfMatching(Class<?> returnType, ServiceManager
> For me it has many benefits:
> 1) It separates completely the annotation processing from the bridge creation,
something which is currently in the way for a refactoring of the programmatic config and
probably a problem
> for non entity based indexing
> 2) Probably future proof for non entity based indexing
> 3) From a development point it treats case #1, #2a and #2b the same way - as
explicitly known bridges (which is really the case)
> 4) There is no major loss in functionality
hibernate-dev mailing list