toedter / spring-hateoas-jsonapi

A JSON:API media type implementation for Spring HATEOAS
Apache License 2.0
107 stars 15 forks source link

JsonApiResourceIdentifier can't recognize spring's EmptyCollectionEmbeddedWrapper? #81

Closed noooonee closed 1 year ago

noooonee commented 1 year ago

Reproduced in Version 2.0.6 / spring boot 3.1.4, with a very simple Spring Data Rest configured.

Got a 500 error when JPA return empty collection. Looks like spring mvc will wrap the result into a wrapped empty collection.

Can't reproduce in the project's example by modified movies to empty, as the example used a custom MovieController, I want to have minimal code with Spring Data Rest convention.

PagedModel { content: [org.springframework.hateoas.server.core.EmbeddedWrappers$EmptyCollectionEmbeddedWrapper@3e560db9], fallbackType: null, metadata: Metadata { number: 0, total pages: 0, total elements: 0, size: 20 }, links: <http://localhost:2222/api/entities?page=0&size=20>;rel="self",<http://localhost:2222/api/profile/entities>;rel="profile",<http://localhost:2222/api/entities/search>;rel="search" }

And in com.toedter.spring.hateoas.jsonapi.JsonApiResourceIdentifier.getResourceField(JsonApiResourceField, Object, JsonApiConfiguration)

As the object is EmptyCollectionEmbeddedWrapper, not the actual entity class, it can't find related JPA ID annotation, and throw exception in line 171:


            if (resourceField == JsonApiResourceField.ID) {
                // then try field "id"
                Field field = ReflectionUtils.findField(object.getClass(), ID_LITERAL);
                //noinspection ConstantConditions
                field.setAccessible(true);
                final Object id = field.get(object);
                if (id == null) {
                    throw new IllegalStateException(CANNOT_COMPUTE_JSON_API_RESOURCE_ID);
                }
                return new ResourceField(ID_LITERAL, id.toString());
            }

Is this by design or I used it in wrong way?

noooonee commented 1 year ago

It's also possible to be handled in

com.toedter.spring.hateoas.jsonapi.JsonApiData.extractContent(Object, boolean, ObjectMapper, JsonApiConfiguration, Map<String, Collection<String>>)

As it invokes com.toedter.spring.hateoas.jsonapi.JsonApiResourceIdentifier.getId(Object, JsonApiConfiguration), which throws this error

toedter commented 1 year ago

thx for reporting this, I will take a look at it soon.

toedter commented 1 year ago

This library is a Spring HATEOS extension and is not supposed to work with Spring DATA REST. Spring DATA REST only supports HAL.