Home > Net >  Hibernate Search 6 @ProjectionConstructor not working
Hibernate Search 6 @ProjectionConstructor not working

Time:10-22

I am experimenting the projection features of Hibernatesearch 6.2.0.Alpha1 before integrating our existing app.

I have created a spring-boot project with JHIPSTER sample project. And added the Hibernate-search dependencies and configurations in both POM.XML and application*.yml. Using JHipster because it helps me with the boilerplate code and fake data.

Have configured pom.xml with both -parameters and jandex. Application runs successfully and loads the data into the database. And i am able to mass Index with the utility we wrote as per the documents.

However when try to search the data with projections we are recieving the error Exception in searchWithProjection() with cause = 'NULL' and exception = 'HSEARCH700112: Invalid object class for projection: com.sample.shop.service.projections.dto.Address. Make sure that this class is mapped correctly, either through annotations (@ProjectionConstructor) or programmatic mapping. If it is, make sure the class is included in a Jandex index made available to Hibernate Search.'. The same query/logic works perfectly fine if we search without projections.

Ex. if you view the files AddressResource.java & AddressService.java in the above linked repository; you can find 2 implementations for projections and no-projections respectively. while the one without projections works perfectly fine the one with projects is throwing the error.

I feel it might be some configuration issue, however not able to figure-out myself. Appreciate your help on configuration / code approach.

Please be informed that I have gone through the follwoing tickets already:

  1. Hibernate Search 6 combine projections not working
  2. Single return type in Hibernate Search

CodePudding user response:

Thanks for your reproducer. It's a bug: https://hibernate.atlassian.net/browse/HSEARCH-4724

I suggested a workaround here: https://github.com/anothergoodguy/spring-data-hibernate-search/pull/1

In short:

  • Add this class to your application:
package com.sample.shop.config;

import java.net.URISyntaxException;
import java.nio.file.Path;
import org.hibernate.search.mapper.orm.mapping.HibernateOrmMappingConfigurationContext;
import org.hibernate.search.mapper.orm.mapping.HibernateOrmSearchMappingConfigurer;
import org.hibernate.search.util.common.jar.impl.JandexUtils;
import org.springframework.stereotype.Component;

@Component("searchMappingConfigurer")
public class HibernateSearchMappingConfigurer implements HibernateOrmSearchMappingConfigurer {

    @Override
    public void configure(HibernateOrmMappingConfigurationContext context) {
        // Workaround for https://hibernate.atlassian.net/browse/HSEARCH-4724
        // => Hibernate Search doesn't seem to find the Jandex index in the fat JAR.
        try {
            var classesUri = getClass().getProtectionDomain().getCodeSource().getLocation().toURI();
            var ssp = classesUri.getSchemeSpecificPart();
            var jarpath = Path.of(ssp.substring(ssp.indexOf(":")   1, ssp.indexOf("!")));
            context.annotationMapping().add(JandexUtils.readIndex(jarpath).get());
        } catch (URISyntaxException e) {
            throw new RuntimeException(e);
        }
    }
}
  • Reference it in your configuration:
  jpa:
    properties:
      hibernate.search.mapping.configurer: bean:searchMappingConfigurer

And voilà.

Note it's just a workaround and relies on internal code that may break at any time. But, well, at least it works, so it's fine until the bug gets fixed.

CodePudding user response:

Here are the instructions to run the application:

All the needed ecosystem like Elasticsearch, kibana and MySql are added in eco.yml file under src/main/docker/eco.yml Please use the following command to bring the ecosystem up docker-compose -f src/main/docker/eco.yml up -d && docker-compose -f src/main/docker/eco.yml logs -f

On a different termina tab/window, Build the application with the following command ./mvnw clean package -Pprod,api-docs -Dskip.Tests -Dmaven.test.skip=true to run the application run the following command java -jar target/shop-app-0.0.1-SNAPSHOT.jar

Once the application is started, it will show that it's listneing on [http://localhost:8080]. Please open the same url on the browser and login with the default administrator User:admin and Password:admin. Then please navigate to swagger from Administrator menu and API menu-item.

We need to Mass-Index the fake data that's is already loaded from swagger from same swagger window: by executing the post on /api/mass/index on the resource Elastic Search Mass Indexing API

Then please go to the address-resource :

  1. Request without Projections access /api/_search/addresses with query string aa - This will result in success
  2. Request with Projections access /_search/addresses/projection with same query string aa - This will result in failure
  • Related