Skip to content

feature: Provide a toEntityList from a set of loaded IDs #539

New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

Open
SylvainAssemat opened this issue Jan 21, 2025 · 2 comments
Open

feature: Provide a toEntityList from a set of loaded IDs #539

SylvainAssemat opened this issue Jan 21, 2025 · 2 comments
Assignees
Labels
enhancement New feature or request v1.0.0

Comments

@SylvainAssemat
Copy link

SylvainAssemat commented Jan 21, 2025

Hi all

I have a question / use case about the load() query usign some MetamodelField

My goal is to have a model (RDUser in my case) with limited attribute (ID only as shown below)

Is this somtehing possible to have a kind of conversion based on MetamodelField in entry, and a List at the end ?

This work

            SearchStream<RDUser> searchStream = entityStream.of(RDUser.class);
            List<Single<String>> list = searchStream
                    //.filter(predicate)
                    //.sorted(comparator)
                    //.skip(pageable.getPageNumber() * pageable.getPageSize())
                    //.limit(pageable.getPageSize())
                    .load(RDUser$.ID)
                    .toList(String.class);

This is not working

  SearchStream<RDUser> searchStream = entityStream.of(RDUser.class);
            Page<RDUser> list = searchStream
                    //.filter(predicate)
                    //.sorted(comparator)
                    //.skip(pageable.getPageNumber() * pageable.getPageSize())
                    //.limit(pageable.getPageSize())
                    .load(RDUser$.ID)
                    .toList(PageRequest.ofSize(50000), RDUser.class);

Exception :

log.info("-> " + list.getContent());

java.lang.NullPointerException: Cannot invoke "Object.toString()" because the return value of "java.util.Map.get(Object)" is null
 AggregationStream<RDUser> aggregationStream = searchStream
                    //.filter(predicate)
                    //.sorted(comparator)
                    //.skip(pageable.getPageNumber() * pageable.getPageSize())
                    //.limit(pageable.getPageSize())
                    .load(RDUser$.ID);

            aggregationStream.aggregate().getResults().stream().forEach(System.out::println);

{id=020cc931-954b-4b42-83c3-49489945ca72}
{id=031dd63d-87c1-4c17-9552-af8d38a4630e}
{id=1780534c-d47b-473c-be92-37dd1342c001}
{id=1f0d13d7-452d-442e-8a7e-5bf384dde960}
{id=2e833aff-0734-4b69-9000-d0e3400ebedd}
{id=46bc80af-ef55-46dd-b890-4e78ae9e0c46}
{id=48edcd36-df7e-44c2-9521-6824104f4e51}
{id=52837167-894a-4542-8468-2f1f97aa857f}
{id=71b478c8-044a-4eb7-8445-0f24d175e209}
{id=83e5e31d-234b-4fb9-b17f-d58f28c5b22f}
{id=9962907a-ec4c-41cc-9902-810d94f3bd32}
{id=ae8e15a2-5940-4dcc-8815-5695d4f8e77f}

This function seems to be the culprit

 @SuppressWarnings("unchecked")
  List<E> toEntityList(AggregationResult aggregationResult) {
    if (isDocument) {
      return aggregationResult.getResults().stream().map(d -> gson.fromJson(d.get("$").toString(), entityClass))
          .toList();
    } else {
      return aggregationResult.getResults().stream()
          .map(h -> (E) ObjectUtils.mapToObject(h, entityClass, mappingConverter)).toList();
    }
  }

Workaround :

//https://github.com/redis/redis-om-spring/issues/474
// @Autowired
// @Qualifier("omGsonBuilder")
// private GsonBuilder gsonBuilder;
Gson gson = gsonBuilder.create(); //Not use jackson

List<RDUser> listRDUser = aggregationStream.aggregate().getResults().stream().map(d -> gson.fromJson(d.toString(), RDUser.class)).toList();
@SylvainAssemat SylvainAssemat changed the title TUPLE to MODEL BUG SERIALISATION (toEntityList) Jan 22, 2025
@SylvainAssemat SylvainAssemat changed the title BUG SERIALISATION (toEntityList) BUG toEntityList Jan 22, 2025
@bsbodden bsbodden self-assigned this Feb 16, 2025
@bsbodden
Copy link
Contributor

Is RDUser annotated with RedisHash or Document? And to be clear you think this happens in toEntityList when it takes the branch that runs return aggregationResult.getResults().stream().map(h -> (E) ObjectUtils.mapToObject(h, entityClass, mappingConverter)).toList();
Based on that, I'm assuming this is RedisHash annotated entity? For RedisHash we delegate the hydration of the object to the mapping converter which is just an extension of the converter from Spring Data Redis.
In the aggregation, once you call load you have an aggregation results that contains only a String (RDUser$.ID). There is not registered converter to convert a single String to an Object. Gson just happens to be smart enough to handle this case.
A better solution might be to provide a .toEntityList(...) method to explicitly force this behavior.

@raphaeldelio @foogaro thoughts?

@bsbodden bsbodden changed the title BUG toEntityList feature: Provide a toEntityList from a set of loaded IDs Mar 8, 2025
@bsbodden bsbodden added the enhancement New feature or request label Mar 8, 2025
@foogaro
Copy link
Contributor

foogaro commented Mar 31, 2025

@SylvainAssemat if I understand correctly, you have a bunch of RDUser objects saved in Redis, where "all" fields have a value.

Now, through the load method you want to specify which fields need to be populated when retrieving the object from Redis.

Am I understanding correctly?

@bsbodden bsbodden assigned foogaro and unassigned bsbodden Apr 4, 2025
# for free to join this conversation on GitHub. Already have an account? # to comment
Labels
enhancement New feature or request v1.0.0
Projects
None yet
Development

No branches or pull requests

3 participants