We have several options here:
It means that whenever includeEmbeddedObjectId = true and the embedded object has an @Id or @DocumentId, we will create a field of type string with the name of that id.
Pros: simple enough to implement.
Not very flexible (can't change the name or type of the ID field)
Very low added value (adding @GenericField on the @Id property would achieve the same effect).
We could take advantage of an ID field in more features:
"id" predicate on the embedded ID: .id().field("myEmbedded").matchingAny(someCollectionOfIds), translated to a match predicate on the embedded ID field.
match predicate on the object field: .match().field("myEmbedded").matching(someManagedEntity), translated to a match predicate on the embedded ID field.
projection to entity references to the embedded entity (by passing the entity name to the backend during mapping, and using that + the projected ID when projecting)
projection to loaded instances of the embedded entity (using the reference and the loader passed by the mapper)
more consistency (same predicate for the root ID and embedded IDs)
more features (especially projections)
more complex to implement, and thus will take more time.
according to the principle of least surprise, we should enable this by default, so that predicates/projections don't fail unexpectedly.
This means an ID field will appear in @IndexedEmbeddeds. For Lucene we can give it some internal name and it won't affect people; for Elasticsearch it's not so easy as it will be very visible in the schema and may conflict with user-defined fields... we should probably provide a way to control how that field is named? "hsearch_id" vs. "id" vs. "whatever the ID property is named" vs. "some custom name"? Or maybe just an attribute in @DocumentId: @DocumentId(fieldNameWhenEmbedded = "...")?