question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

@JsonValue fails for Java Record

See original GitHub issue

Version information 2.12.1 OpenJDK 15.0.1

To Reproduce

Given:

public final record GetLocations(@JsonValue Map<String, URI> nameToLocation)
{
	@JsonCreator
	public GetLocations(Map<String, URI> nameToLocation)
	{
		assertThat(nameToLocation, "nameToLocation").isNotNull();
		this.nameToLocation = new HashMap<>(nameToLocation);
	}
}

I am expecting Jackson to serialize the Map to JSON but instead I get the following exception:

Problem with definition of [AnnotedClass GetLocations]: Multiple 'as-value' properties defined ([field GetLocations#nameToLocation] vs [method GetLocations#nameToLocation()])

Issue Analytics

  • State:open
  • Created 3 years ago
  • Reactions:5
  • Comments:8 (6 by maintainers)

github_iconTop GitHub Comments

1reaction
yihtsernscommented, Nov 9, 2022

…though ideologically, I’d prefer to serialize the return value of the getter than the field…

@cowwoc you can remove the @JsonValue annotation from the Record header, and annotate the accessor instead:

public final record GetLocations(Map<String, URI> nameToLocation)
{
	@JsonCreator
	public GetLocations(Map<String, URI> nameToLocation)
	{
		assertThat(nameToLocation, "nameToLocation").isNotNull();
		this.nameToLocation = new HashMap<>(nameToLocation);
	}

	@JsonValue
	@Override
	public Map<String, URI> nameToLocation()
	{
		return nameToLocation;
        }
}

A Trick

Since this issue is caused by (auto-)propagation of annotation on Records components, we learn that the decision to propagate the annotation to either field and/or accessor method is decided by the @Target supported by the annotation itself.

Since @JsonValue can be annotated on ElementType.FIELD & ElementType.METHOD, it gets propagated to both. Knowing this, you can create a custom meta-annotation for @JsonValue that targets only ElementType.METHOD:

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
@JacksonAnnotationsInside
@JsonValue
public @interface JsonValueAccessor {
}

Then this will then work:

public final record GetLocations(@JsonValueAccessor Map<String, URI> nameToLocation) // Your custom annotation
{
	@JsonCreator
	public GetLocations(Map<String, URI> nameToLocation)
	{
		assertThat(nameToLocation, "nameToLocation").isNotNull();
		this.nameToLocation = new HashMap<>(nameToLocation);
	}
}
0reactions
pjfanningcommented, Dec 13, 2021

thanks @cowtowncoder - must be something else going on that is causing the scala 3 stuff not to work

Read more comments on GitHub >

github_iconTop Results From Across the Web

java - Unable to deserialize when using new Record classes
I get that the error is saying the record has no constructors, but from what I see the record class takes care of...
Read more >
Jackson JSON - Using @JsonValue to serialize a single value ...
@JsonValue annotation is used to indicate that the return value of annotated method (with no args) is to be used as the single...
Read more >
Jackson JSON Java Parser API Example Tutorial - DigitalOcean
trying to unmarshal a JSON in to JAVA POJO. but, I can't seem to resolve this error. would anyone be able to assist...
Read more >
10: 9.15. JSON Functions and Operators - PostgreSQL
The field/element/path extraction operators return NULL, rather than failing, if the JSON input does not have the right structure to match the request; ......
Read more >
Json.Decode - json 1.1.3 - Elm Packages
Parse the given string into a JSON value and then run the Decoder on it. This will fail if the string is not...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found