lechonex
lechonex

Reputation: 165

HSEARCH800007 error in Hibernate Search 6.2.2: Unable to resolve path after specifying the indexing dependency

I have a parent Document class that has subclasses with different types of documents (DocumentInvoice, DocumentReportPublication, etc).

This document can be linked to other documents so I have a ManyToMany association with itself. I have also another method to generate content in the Hibernate Search index only with invoices to store some of the fields:

@Entity
@Table(name = "DOCUMENT")
@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
@DiscriminatorColumn(name = "DOCUMENT_TYPE_DISCRIMINATOR", discriminatorType = DiscriminatorType.STRING)
@Getter
@Setter
@EqualsAndHashCode(of = "id", callSuper = false)
public class Document {

...

    @Column(name = "TITLE")
    @KeywordField(name = "title_original", projectable = Projectable.YES, sortable = Sortable.YES, normalizer = "caseInsensitiveNormalizer")
    @FullTextField(name = "title", projectable = Projectable.YES, analyzer = "caseInsensitiveWhitespaceAnalyzer")
    private String title;

    @ManyToMany
    @JoinTable(
        name = "document_linked_document",
        joinColumns = {
            @JoinColumn(name = "document_id", referencedColumnName = "document_id"),
            @JoinColumn(name = "document_partition_id", referencedColumnName = "document_partition_id")
        },
        inverseJoinColumns = {
            @JoinColumn(name = "linked_document_id", referencedColumnName = "document_id"),
            @JoinColumn(name = "linked_document_partition_id", referencedColumnName = "document_partition_id")
        })
    @IndexedEmbedded(includePaths = {"title"})
    @IndexingDependency(reindexOnUpdate = ReindexOnUpdate.SHALLOW)
    private Set<Document> linkedDocuments = new LinkedHashSet<>();

...
@IndexedEmbedded(name = "invoices", includePaths = {
        "title", "paymentReceived", "dateReceived"
    })
    @IndexingDependency(
        derivedFrom = @ObjectPath(@PropertyValue(propertyName = "linkedDocuments"))
    )
    @AssociationInverseSide(
        inversePath = @ObjectPath(@PropertyValue(propertyName = "linkedDocuments"))
    )
    public List<DocumentInvoice> getLinkedInvoices() {
        return this.getLinkedDocuments().stream()
            .filter(document -> document instanceof DocumentInvoice)
            .map(document -> (DocumentInvoice) document)
            .collect(Collectors.toList());
    }
}

I have set up the inverse side association so that if there is a change in the linked invoice (for instance the payment status or the amounts) the index gets updated.

It works but I am getting a lot of warnings in the logs:

2023-11-29 09:16:56 org.hibernate.search.mapper.pojo.automaticindexing.building.impl.PojoImplicitReindexingResolverBuildingHelper [WARN] HSEARCH700122: An unexpected failure occurred while configuring resolution of association inverse side for reindexing. This may lead to incomplete reindexing and thus out-of-sync indexes. The exception is being ignored to preserve backwards compatibility with earlier versions of Hibernate Search. Failure: HSEARCH800007: Unable to resolve path '.linkedInvoices' to a persisted attribute in Hibernate ORM metadata. If this path points to a transient attribute, use @IndexingDependency(derivedFrom = ...) to specify which persisted attributes it is derived from. See the reference documentation for more information. -- this may indicate a bug or a missing test in Hibernate Search. Please report it: https://hibernate.org/community/ Context: type 'com.penman.core.domain.DocumentInvoice', path '.linkedInvoices<collection>' Association inverse side: {HibernateOrmClassRawTypeModel[com.penman.core.domain.DocumentInvoice]=PojoModelPathValueNode[.linkedDocuments<collection>]}.^M
org.hibernate.search.util.common.AssertionFailure: HSEARCH800007: Unable to resolve path '.linkedInvoices' to a persisted attribute in Hibernate ORM metadata. If this path points to a transient attribute, use @IndexingDependency(derivedFrom = ...) to specify which persisted attributes it is derived from. See the reference documentation for more information. -- this may indicate a bug or a missing test in Hibernate Search. Please report it: https://hibernate.org/community/
        at org.hibernate.search.mapper.pojo.automaticindexing.building.impl.PojoImplicitReindexingResolverBuildingHelper.createResolversByOrdinal(PojoImplicitReindexingResolverBuildingHelper.java:201) ~[hibernate-search-mapper-pojo-base-6.2.2.Final.jar:6.2.2.Final]
        at org.hibernate.search.mapper.pojo.automaticindexing.building.impl.PojoImplicitReindexingResolverBuildingHelper.createAssociationInverseSideResolver(PojoImplicitReindexingResolverBuildingHelper.java:152) ~[hibernate-search-mapper-pojo-base-6.2.2.Final.jar:6.2.2.Final]
        at org.hibernate.search.mapper.pojo.automaticindexing.building.impl.PojoImplicitReindexingResolverBuilder.build(PojoImplicitReindexingResolverBuilder.java:114) ~[hibernate-search-mapper-pojo-base-6.2.2.Final.jar:6.2.2.Final]
        at org.hibernate.search.mapper.pojo.automaticindexing.building.impl.PojoImplicitReindexingResolverBuildingHelper.buildOptional(PojoImplicitReindexingResolverBuildingHelper.java:132) ~[hibernate-search-mapper-pojo-base-6.2.2.Final.jar:6.2.2.Final]
        at org.hibernate.search.mapper.pojo.automaticindexing.building.impl.PojoImplicitReindexingResolverBuildingHelper.build(PojoImplicitReindexingResolverBuildingHelper.java:112) ~[hibernate-search-mapper-pojo-base-6.2.2.Final.jar:6.2.2.Final]
        at org.hibernate.search.mapper.pojo.mapping.building.impl.PojoIndexedTypeManagerBuilder.buildAndAddTo(PojoIndexedTypeManagerBuilder.java:128) ~[hibernate-search-mapper-pojo-base-6.2.2.Final.jar:6.2.2.Final]
        at org.hibernate.search.mapper.pojo.mapping.building.impl.PojoMapper.prepareBuild(PojoMapper.java:287) ~[hibernate-search-mapper-pojo-base-6.2.2.Final.jar:6.2.2.Final]
        at org.hibernate.search.engine.common.impl.SearchIntegrationBuilder$MappingBuildingState.partiallyBuildAndAddTo(SearchIntegrationBuilder.java:288) ~[hibernate-search-engine-6.2.2.Final.jar:6.2.2.Final]
        at org.hibernate.search.engine.common.impl.SearchIntegrationBuilder.prepareBuild(SearchIntegrationBuilder.java:189) ~[hibernate-search-engine-6.2.2.Final.jar:6.2.2.Final]
        at org.hibernate.search.mapper.orm.bootstrap.impl.HibernateSearchPreIntegrationService$NotBooted.doBootFirstPhase(HibernateSearchPreIntegrationService.java:279) ~[hibernate-search-mapper-orm-6.2.2.Final.jar:6.2.2.Final]
        at org.hibernate.search.mapper.orm.bootstrap.impl.HibernateOrmIntegrationBooterImpl.bootNow(HibernateOrmIntegrationBooterImpl.java:179) ~[hibernate-search-mapper-orm-6.2.2.Final.jar:6.2.2.Final]
........
Caused by: org.hibernate.search.util.common.SearchException: HSEARCH800007: Unable to resolve path '.linkedInvoices' to a persisted attribute in Hibernate ORM metadata. If this path points to a transient attribute, use @IndexingDependency(derivedFrom = ...) to specify which persisted attributes it is derived from. See the reference documentation for more information.
        at org.hibernate.search.mapper.orm.model.impl.HibernateOrmPathInterpreter.property(HibernateOrmPathInterpreter.java:313) ~[hibernate-search-mapper-orm-6.2.2.Final.jar:6.2.2.Final]
        at org.hibernate.search.mapper.orm.model.impl.HibernateOrmPathInterpreter.property(HibernateOrmPathInterpreter.java:162) ~[hibernate-search-mapper-orm-6.2.2.Final.jar:6.2.2.Final]
        at org.hibernate.search.mapper.pojo.model.path.spi.PojoModelPathBinder.applyPath(PojoModelPathBinder.java:45) ~[hibernate-search-mapper-pojo-base-6.2.2.Final.jar:6.2.2.Final]
        at org.hibernate.search.mapper.pojo.model.path.spi.PojoModelPathBinder.applyPath(PojoModelPathBinder.java:30) ~[hibernate-search-mapper-pojo-base-6.2.2.Final.jar:6.2.2.Final]
        at org.hibernate.search.mapper.pojo.model.path.spi.PojoModelPathBinder.bind(PojoModelPathBinder.java:25) ~[hibernate-search-mapper-pojo-base-6.2.2.Final.jar:6.2.2.Final]
        at org.hibernate.search.mapper.orm.model.impl.HibernateOrmPathInterpreter.interpretPath(HibernateOrmPathInterpreter.java:274) ~[hibernate-search-mapper-orm-6.2.2.Final.jar:6.2.2.Final]
        at org.hibernate.search.mapper.orm.model.impl.HibernateOrmPathDefinitionProvider.interpretPath(HibernateOrmPathDefinitionProvider.java:54) ~[hibernate-search-mapper-orm-6.2.2.Final.jar:6.2.2.Final]
        at java.base/java.util.HashMap.computeIfAbsent(HashMap.java:1220) ~[?:?]
        at org.hibernate.search.mapper.pojo.model.path.impl.PojoRuntimePathsBuildingHelper.toPathDefinition(PojoRuntimePathsBuildingHelper.java:39) ~[hibernate-search-mapper-pojo-base-6.2.2.Final.jar:6.2.2.Final]
        at org.hibernate.search.mapper.pojo.automaticindexing.building.impl.PojoImplicitReindexingResolverBuildingHelper.createResolversByOrdinal(PojoImplicitReindexingResolverBuildingHelper.java:175) ~[hibernate-search-mapper-pojo-base-6.2.2.Final.jar:6.2.2.Final]
        ... 127 more
Caused by: org.hibernate.MappingException: property [linkedInvoices] not found on entity [com.penman.core.domain.DocumentInvoice]
        at org.hibernate.mapping.PersistentClass.getProperty(PersistentClass.java:517) ~[hibernate-core-5.6.15.Final.jar:5.6.15.Final]
        at org.hibernate.mapping.PersistentClass.getProperty(PersistentClass.java:528) ~[hibernate-core-5.6.15.Final.jar:5.6.15.Final]
        at org.hibernate.search.mapper.orm.model.impl.HibernateOrmPathInterpreter.property(HibernateOrmPathInterpreter.java:303) ~[hibernate-search-mapper-orm-6.2.2.Final.jar:6.2.2.Final]
        at org.hibernate.search.mapper.orm.model.impl.HibernateOrmPathInterpreter.property(HibernateOrmPathInterpreter.java:162) ~[hibernate-search-mapper-orm-6.2.2.Final.jar:6.2.2.Final]
        at org.hibernate.search.mapper.pojo.model.path.spi.PojoModelPathBinder.applyPath(PojoModelPathBinder.java:45) ~[hibernate-search-mapper-pojo-base-6.2.2.Final.jar:6.2.2.Final]
        at org.hibernate.search.mapper.pojo.model.path.spi.PojoModelPathBinder.applyPath(PojoModelPathBinder.java:30) ~[hibernate-search-mapper-pojo-base-6.2.2.Final.jar:6.2.2.Final]
        at org.hibernate.search.mapper.pojo.model.path.spi.PojoModelPathBinder.bind(PojoModelPathBinder.java:25) ~[hibernate-search-mapper-pojo-base-6.2.2.Final.jar:6.2.2.Final]
        at org.hibernate.search.mapper.orm.model.impl.HibernateOrmPathInterpreter.interpretPath(HibernateOrmPathInterpreter.java:274) ~[hibernate-search-mapper-orm-6.2.2.Final.jar:6.2.2.Final]
        at org.hibernate.search.mapper.orm.model.impl.HibernateOrmPathDefinitionProvider.interpretPath(HibernateOrmPathDefinitionProvider.java:54) ~[hibernate-search-mapper-orm-6.2.2.Final.jar:6.2.2.Final]
        at java.base/java.util.HashMap.computeIfAbsent(HashMap.java:1220) ~[?:?]
        at org.hibernate.search.mapper.pojo.model.path.impl.PojoRuntimePathsBuildingHelper.toPathDefinition(PojoRuntimePathsBuildingHelper.java:39) ~[hibernate-search-mapper-pojo-base-6.2.2.Final.jar:6.2.2.Final]
        at org.hibernate.search.mapper.pojo.automaticindexing.building.impl.PojoImplicitReindexingResolverBuildingHelper.createResolversByOrdinal(PojoImplicitReindexingResolverBuildingHelper.java:175) ~[hibernate-search-mapper-pojo-base-6.2.2.Final.jar:6.2.2.Final]
        ... 127 more

As I said DocumentInvoice is one of the subclasses of the Document class, as it is a type of Document:

@Entity
@DiscriminatorValue("INVOICE")
@Table(name = "INVOICE")
@Indexed
@Getter
@Setter
public class DocumentInvoice extends Document {
...
    @GenericField(projectable = Projectable.YES)
    @Column(name="PAYMENT_RECEIVED")
    private Boolean paymentReceived;

    @GenericField(projectable = Projectable.YES)
    @Column(name="DATE_RECEIVED")
    private LocalDate dateReceived;
...
}

As suggested in the warning I have set up the @IndexingDependency and the @AssociationInverseSide so I don't understand why we are getting an error. I have tried to move the inverse association to the linkedDocuments property and the result is the same. The documentation shows simpler scenarios and I think it could be related to be doing a relationship with itself.

This seems not to be a problem now, but according to the logs could be an issue in future versions. What are we doing wrong? Could this be an HS6 bug?

EDIT:

At the end adding an extra @AssociationInverseSide to the linkedDocuments (so leaving it in both places) and removing the @IndexingDependency there made it to work without the error message:

    @ManyToMany
    @JoinTable(
        name = "document_linked_document",
        joinColumns = {
            @JoinColumn(name = "document_id", referencedColumnName = "document_id"),
            @JoinColumn(name = "document_partition_id", referencedColumnName = "document_partition_id")
        },
        inverseJoinColumns = {
            @JoinColumn(name = "linked_document_id", referencedColumnName = "document_id"),
            @JoinColumn(name = "linked_document_partition_id", referencedColumnName = "document_partition_id")
        })
    @IndexedEmbedded(includePaths = {"title"})
    @AssociationInverseSide(
        inversePath = @ObjectPath(@PropertyValue(propertyName = "linkedDocuments"))
    )
    private Set<Document> linkedDocuments = new LinkedHashSet<>();

Upvotes: 0

Views: 273

Answers (1)

yrodiere
yrodiere

Reputation: 9977

I think this is the cause of your problem:

@IndexedEmbedded(name = "invoices", includePaths = {
        "title", "paymentReceived", "dateReceived"
    })
    @IndexingDependency(
        derivedFrom = @ObjectPath(@PropertyValue(propertyName = "linkedDocuments"))
    )
    @AssociationInverseSide(
        inversePath = @ObjectPath(@PropertyValue(propertyName = "linkedDocuments"))
    )
    public List<DocumentInvoice> getLinkedInvoices() {

Because Hibernate Search assumes annotations refer to "extracted" elements by default, the IndexingDependency annotation basically says "elements of linkedInvoices are derived from elements of linkedDocuments".

Whereas what you need to tell Hibernate Search is "the (whole) list linkedInvoices is derived from elements of linkedDocuments". Otherwise Hibernate Search will try to resolve linkedInvoices as an association first, which obviously won't work.

I know it's not intuitive (at all), though. https://hibernate.atlassian.net/browse/HSEARCH-4271 should hopefully fix this one day, when we get time to work on it.

EDIT: Also, you should probably remove the @AssociationInverseSide from getLinkedInvoices, as I don't think this really is the inverse side of linkedDocuments.

This should work better:

@IndexedEmbedded(name = "invoices", includePaths = {
        "title", "paymentReceived", "dateReceived"
    })
    @IndexingDependency(
        derivedFrom = @ObjectPath(@PropertyValue(propertyName = "linkedDocuments")),
        // ADD THIS
        extraction = @ContainerExtraction(extract = ContainerExtract.NO)
    )
    public List<DocumentInvoice> getLinkedInvoices() {

Upvotes: 2

Related Questions