Recursive @IndexEmbedded problem

Hello,

I followed chapter 6.6.8. Filtering embedded fields and breaking @IndexedEmbedded cycles but I don’t manage to make it works.
I am facing to a recursive problem with @IndexEmbedded, here the code :

@Entity
@Indexed
public class Depot extends BasicDepot implements IArchivable, ISearchableParapheur {

//Many fields indexed in this class or superclass BasicDepot

@GenericField(name = REGULARISE)
    protected Boolean regularise;

@ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "depot_initial_fk")
    protected Depot depotInitial;

@IndexedEmbedded(includeEmbeddedObjectId = true, includePaths = {
			Depot_.REGULARISE
	})
	public Depot getDepotInitial() {
		return this.depotInitial;
	}

}

And the error message :

Hibernate ORM mapping:
type ‘com.allegoria.notariat.business.Depot’:
failures:
- HSEARCH000216: An @IndexedEmbedded defines includePaths filters that do not match anything. Non-matching includePaths filters: [depotInitial]. Encountered field paths: [acquittement,…

So I’am defining the depotInitial index name, why HSearch is saying “Non-matching includePaths” ?

Thanks you.

But the indexing of a Set is working :

@IndexedEmbedded(includePaths = {
			Depot_.CODE_WORKFLOW,
			//Depot_.DEPOT_INITIAL,
			Depot_.REGULARISE
	})
	@IndexingDependency(derivedFrom = {
			@ObjectPath({@PropertyValue(propertyName = Depot_.CODE_WORKFLOW)}),
			//@ObjectPath({@PropertyValue(propertyName = Depot_.DEPOT_INITIAL)}),
			@ObjectPath({@PropertyValue(propertyName = Depot_.REGULARISE)})
	})
	public Set<Depot> getDepotsComplementaires() {
		return depotsComplementaires;
	}

When I try to index depotInitial like above, it causes troubles.

I don’t think depotInitial itself is a value field? It’s just an object field that happens to contain value fields.

includePaths is meant to list every single path explicitly. You can’t just list an object field and expect its contained fields to be included.

You probably want something like that?

@IndexedEmbedded(includePaths = {
			Depot_.CODE_WORKFLOW,
			Depot_.REGULARISE,
			Depot_.DEPOT_INITIAL + "." + Depot_.CODE_WORKFLOW,
			Depot_.DEPOT_INITIAL + "." + Depot_.REGULARISE,
	})
	public Set<Depot> getDepotsComplementaires() {
		return depotsComplementaires;
	}

Unrelated to your question, note that you don’t need to use @IndexingDependency(derivedFrom = ...) on a persisted field (which depotsComplementaires seems to be? Hard to say without the full mapping, though).
@IndexingDependency(derivedFrom = ...) is mostly useful for fields that are… derived, so not “directly” persisted. If depotsComplementaires is a (bi-directional) association (i.e. @OneToMany or @ManyToMany), in the mapping above Hibernate Search will be able to infer that whenever a depotComplementaire has its “code workflow” or “regularise” property modified, then the entity pointing to that depotComplementaire has to be reindexed.

Sorry I missed some code :

@Entity
@Indexed
public class Depot extends BasicDepot implements IArchivable, ISearchableParapheur {

@OneToMany(mappedBy = Depot_.DEPOT_INITIAL)
    protected Set<Depot> depotsComplementaires = new HashSet<>();

}

Indeed, there is a relation between depotsComplementaires and depotInitial, your mapping should be right. But, I don’t really understand your explanation :

includePaths is meant to list every single path explicitly. You can’t just list an object field and expect its contained fields to be included.

Suppose that depotInital was a relation to another entity. It is possible to do on the getter :

@IndexEmbedded(includePath={
OTHERENTITY_.INDEXED_FIELD_A,
OTHERENTITY_.INDEXED_FIELD_B,
etc.
})
public OtherEntity getOtherEntity() {
 return this.otherEntity;
}

But if OtherEntity = Depot , this is my case, it doesn’t work. I don’t really see the difference in the mapping.
Furthermore, depotsComplementaires is not a value field either, no more than depotInitial. The only one difference is that one is a Set and the other only Depot. By the way, depotsComplementaires is probably a set of only one element because the join column depot_acte_fk stores only one value (not a join table)

thanks.

EDIT :

I tried with :

@IndexedEmbedded(includeEmbeddedObjectId = true, includePaths = {
			Depot_.CODE_WORKFLOW,
			Depot_.DEPOT_INITIAL + "." + Depot_.ID,
			Depot_.REGULARISE
	})
	public Set<Depot> getDepotsComplementaires() {
		return depotsComplementaires;
	}

But I still have error :

Hibernate ORM mapping:
type ‘com.allegoria.notariat.business.Depot’:
failures:
- HSEARCH000216: An @IndexedEmbedded defines includePaths filters that do not match anything. Non-matching includePaths filters: [depotInitial.id]. Encountered field paths: [acquittement,

The main difference is that your example with OtherEntity references value fields, i.e. integers, strings, etc. When you list Depot_.DEPOT_INITIAL, you actually are referencing an object field. One that doesn’t hold a value, but merely aggregates other fields that do have a value (integers, strings, etc.).

Just including Depot_.DEPOT_INITIAL, and not its contained fields (e.g. depotInitial.regularise), is pointless, because the resulting object (depotInitial) will be empty.

However, I must admit I am surprised that listing Depot_.DEPOT_INITIAL triggers an error. I would have expected Hibernate Search to just comply and include a useless, empty object field in your index schema.

Okay, this is even stranger, considering you have an @IndexedEmbedded(includedEmbeddedObjectId = true) on getDepotInitial().

Can you try to create a reproducer? Then I can have a closer look and determine if there’s a problem in the mapping, or a bug to fix.

You will find test case templates here; please use them: hibernate-test-case-templates/search/hibernate-search-6 at main · hibernate/hibernate-test-case-templates · GitHub

Just including Depot_.DEPOT_INITIAL , and not its contained fields (e.g. depotInitial.regularise ), is pointless, because the resulting object ( depotInitial ) will be empty.

On my initial post, I included field :

@IndexedEmbedded(includeEmbeddedObjectId = true, includePaths = {
			Depot_.REGULARISE
	})
	public Depot getDepotInitial() {
		return this.depotInitial;
	}

I always indexed fields in includePaths. And maybe not as useless as you said because the Query DSL exists() can be verified (or not).

Considering the problem with mass indexer below :

@IndexedEmbedded(includeEmbeddedObjectId = true, includePaths = {
			Depot_.CODE_WORKFLOW,
			**Depot_.DEPOT_INITIAL + "." + Depot_.ID,**
			Depot_.REGULARISE
	})
	public Set<Depot> getDepotsComplementaires() {
		return depotsComplementaires;
	}

(The problem is bold quoted) - I will try with your vanilla exemple you linked.
But I think, that I have to forget indexing depotInitial. Indeed, depotComplementaires IS the depotInitial. So just indexing depotComplementaires seems to be sufficient according to Hibernate ORM mapping.