Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

Map content in an EntityModel is not properly unwrapped #1157

Closed
dawi opened this issue Dec 10, 2019 · 4 comments
Closed

Map content in an EntityModel is not properly unwrapped #1157

dawi opened this issue Dec 10, 2019 · 4 comments
Assignees
Labels
in: core Core parts of the project type: bug
Milestone

Comments

@dawi
Copy link

dawi commented Dec 10, 2019

@JsonUnwrapped is ignored if EntityModel.content is a Map.

This seems to be a Jackson issue (FasterXML/jackson-databind#171) but it would be nice if the user would not have to figure this out the hard way.

Some thoughts

1. It would be great if EntityModel could be fixed

But I am afraid that there is no simple solution to this issue.
See @odrotbohm comments in this thread: FasterXML/jackson-databind#171 (comment)

2. Validation

There already is a validation that checks if the content is a Collection.
Maybe the validation can also check if the content is a Map:

Assert.notNull(content, "Content must not be null!");
Assert.isTrue(!(content instanceof Collection), "Content must not be a collection! Use Resources instead!");
Assert.isTrue(!(content instanceof Map), "Content must not be a map! Use Resources instead!");

3. MapModel

It would be great to have a MapModel provided by Spring HATEOAS.

public class MapModel extends RepresentationModel<MapModel> {

    private final Map<String, Object> content;

    public MapModel(Map<String, Object> content) {
        this.content = content;
    }

    @JsonAnyGetter
    public Map<String, Object> getContent() {
        return content;
    }
}
@odrotbohm
Copy link
Member

As indicated in the linked ticket, there is a POC for this that allows us to refrain from adding yet another representation model base class just to work around a (current) limitation of Jackson.

It's all in the works, I just haven't gotten to finish it given all the other fixes I had on my table the last couple of days.

@odrotbohm odrotbohm added this to the 1.1.0.M1 milestone Dec 10, 2019
@odrotbohm odrotbohm self-assigned this Dec 10, 2019
@odrotbohm odrotbohm changed the title @JsonUnwrapped is ignored if EntityModel.content is a Map Map content in an EntityModel is not properly unwrapped Dec 11, 2019
@odrotbohm odrotbohm added in: core Core parts of the project type: bug labels Dec 11, 2019
odrotbohm added a commit that referenced this issue Dec 11, 2019
…nstances.

We now register a custom serializer to massage EntityModel instances into dedicated types that – in case of a Map being the content of the entity model – wrap the model into a type that applies the necessary Jackson tweaks to properly unwrap a Map.
@odrotbohm
Copy link
Member

That's in place now. Also backported in the context of #1158.

odrotbohm added a commit that referenced this issue Dec 11, 2019
…g, Object> content.

We now keep internal methods in EntityModel that are configured using Jackson annotations so that it'd populate the content with a Map in case Map<String, Content> is defined as payload type.
odrotbohm added a commit that referenced this issue Dec 12, 2019
Using a custom serializer seems to break downstream projects that also register serializers for EntityModel. We're now using extra methods on EntityModel itself that do the trick as well.
odrotbohm added a commit that referenced this issue Dec 12, 2019
Using a custom serializer seems to break downstream projects that also register serializers for EntityModel. We're now using extra methods on EntityModel itself that do the trick as well.
@abinet
Copy link

abinet commented Jun 6, 2020

Hi all,
I'm currently have an issue with the latest changes in EntityModel<Map<String, Object>>
It seems now we are getting the map's content duplicated on serialization.

	@Test
	public void testSerialization() throws JsonProcessingException {
		final HashMap map = new HashMap();
		map.put("field1", "value1");
		final String serialized = new ObjectMapper().writeValueAsString(new EntityModel<>(map));

		System.out.println(serialized);
	}
{"content":{"field1":"value1"},"links":[],"field1":"value1"}

Is it how it is supposed to be?

spring-hateoas:1.4.0.RELEASE
spring-boot:2.2.6.RELEASE
com.fasterxml.jackson.core:jackson-databind:2.10.3

@mika91
Copy link

mika91 commented Jun 26, 2020

same here (spring-hateoas:1.1.0, jackson:2.11.0, spring-boot:2.3.1)

EDIT: just checked the source code, unit tests behaves simillary

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
in: core Core parts of the project type: bug
Projects
None yet
Development

No branches or pull requests

4 participants