Support runtime polymorphism on associations (instead of defining the indexed properties based on the returned type)

Description

When using @IndexedEmbedded on a set/list of parent/top classes the @Field annotations in the child classes are not picked up and indexed.

@IndexedEmbedded(depth=100)
@OneToMany(fetch = FetchType.LAZY, mappedBy = "top", cascade = CascadeType.ALL)
public Set<Parent> getParents() {
return parents;
}

public class Child extends Parent {
private String childName;
@Field(name = "childName", index=Index.TOKENIZED) // This field is not picked up!!!
.
.
}

Environment

Jboss 4.2.3.GA
Hibernate Core 3.2
Hibernate Search 3.1.1.GA

Activity

Show:
Sanne Grinovero
March 20, 2011, 11:55 PM

hi, yes as you suggested on the forums the starting point for this code would be the DocumentBuilder implementations, in particular org.hibernate.search.engine.DocumentBuilderIndexedEntity. I'm not sure about package names on .Net, I hope you can find it. (how old is the .net implementation? still maintained current with all latest improvements from the Java version?)

The metadata (name of an instance variable) is now built by scanning the annotations on the type itself, which results and reading recursively on the types. so it's about static mapping. I guess the hard part is to find all extending types while this scanning happens, so to build instead a set of alternative mappings being used according to the runtime type, and then use this runtime type instead of the static type.

Geir-Magnus Pettersen
March 21, 2011, 9:11 AM

It looks like not much has happened in the last year at least regarding NHibernate.Search. The last commit I can find has this description. Port from H.Search 3.1: Change from loading entities one by one to loading all using the IN clause. But I found the DocumentBuilder class and will start to experiment a little with it. Thanks so far Sanne!

Michael Hum
April 13, 2018, 5:52 PM

This is quite an old ticket, but I am seeing the same behaviour with our application (hibernate 5.1.10.final, search 5.6.4 final).

We have an entity A with field "address" of abstract type B. B has three possible concrete classes: B1, B2, or B3.

Annotating "address" as @IndexedEmbeddable only indexes the fields in the abstract class.

Any updates? Is this a planned feature to add still?

Sanne Grinovero
April 15, 2018, 9:45 PM

Hi , good question. We're re-designing the whole DocumentBuilder to address several limitations for Hibernate Search 6, we could explore this idea as well.

I'll talk about it with the team but keep in mind that we'll need to have a full definition of the schema at bootstrap, so there will be need for some limitation. For example I'm thinking we would only be able to include in the upfront-known definition the mapped entities from the domain model - not including other sub types. Even in this case I'm not sure if just guessing that all fields from all subtypes of an indexed type should be considered, people will likely want some more control on this.

How would you see the mapping work best for your use case?

Yoann Rodière
April 16, 2018, 7:12 AM

I think we should be able to add support for polymorphism in @IndexedEmbedded, e.g. when encountering @IndexedEmbedded private A a;, consider the mapping of not only A, but also its subclasses B, C, ... That would only be possible for entity types, though, where we know all the subtypes upfront.

That being said, there would be some challenges:

  1. This feature would imply defining fields from different classes (B}, C, ...) in the exact same place in the index schema.

    • We would have to allow some conflicts: fields contributed from different entity types with the same name, but the exact same options, or "compatible" options (if one contribution declares the storage type as "default", then it's compatible with another declaring it as "yes" or "no")

    • ... while preventing others: fields contributed from the same entity type, or from a supertype and one of its subtypes, with the same name, fields contributed from different entity types with the same name and different options

  2. This feature could conflict with some support we have for inheritance in 6. For instance if you define a property with type T in entity type A, annotated with @Field, and override the getter in the entity subtype B to have type U (with U extends T), Hibernate Search will correctly look for a bridge taking U as an input. If we have to take into account multiple entity subtypes B, C, D, etc., each overriding the property to have a different type V, W, ... this could get wildly complicated really fast.

  3. This feature would make the indexing process more complex. That would be manageable, but the problem is this would consequently make automatic reindexing when a contained entity changes more complex, too. And that part is already quite complex...

Also worth mentioning, part (if not all) of the problematics mentioned above are very similar to the ones we would face if we allowed multiple indexed types to be stored in the same index in Hibernate Search 6. And we decided against it in order to keep things simple and to not have to work around the decisions that were taken in Elasticsearch 6.

So can have a look, but let's keep in mind this has some implications that make the feature far from trivial to implement.
Moving this to version 6 so that we don't forget to have a look.

Assignee

Unassigned

Reporter

Ted Williams

Labels

None

Suitable for new contributors

None

Pull Request

None

Feedback Requested

None

Components

Fix versions

Affects versions

Priority

Major
Configure