Given this class
@RequiredArgsConstructor()
public class ResponseObject
{
public final String id;
}
And this simple code:
final String json = "{\"id\":\"123\"}";
final ObjectMapper objectMapper = new ObjectMapper();
final ResponseObject responseObject1 = objectMapper.readValue(json, ResponseObject.class);
Produces the following exception:
com.fasterxml.jackson.databind.exc.MismatchedInputException: Cannot construct instance of `dropbear.ResponseObject` (although at least one Creator exists): cannot deserialize from Object value (no delegate- or property-based Creator)
at [Source: (String)"{"id":"123"}"; line: 1, column: 2]
Switching back to 1.16.18 resolves the error. Any Suggestions?
This is highly likely to be caused by the fact that later versions of
lombok do not put a @Generated annotation on the generated constructor.
Mostly because java 9 puts that annotation semi-out of reach.
There is a lombok property to put that back, or you can put the
@JsonCreator annotation on the constructor by hand.
Disclaimer: I am not a member of the lombok team, I just lurk here ;-)
On Thu, Mar 15, 2018 at 5:45 PM, John Norton notifications@github.com
wrote:
Given this class
@RequiredArgsConstructor()
public class ResponseObject
{
public final String id;
}And this simple code:
final String json = "{\"id\":\"123\"}";
final ObjectMapper objectMapper = new ObjectMapper();
final ResponseObject responseObject1 = objectMapper.readValue(json, ResponseObject.class);Produces the following exception:
com.fasterxml.jackson.databind.exc.MismatchedInputException: Cannot construct instance of
dropbear.ResponseObject(although at least one Creator exists): cannot deserialize from Object value (no delegate- or property-based Creator)
at [Source: (String)"{"id":"123"}"; line: 1, column: 2]Switching back to 1.16.18 resolves the error. Any Suggestions?
—
You are receiving this because you are subscribed to this thread.
Reply to this email directly, view it on GitHub
https://github.com/rzwitserloot/lombok/issues/1612, or mute the thread
https://github.com/notifications/unsubscribe-auth/AAKCRdIgC0WHmZwnu8EPR_9PJSHB1oHuks5tepq5gaJpZM4SsgNP
.
--
"Don't only practice your art, but force your way into it's secrets, for it
and knowledge can raise men to the divine."
-- Ludwig von Beethoven
Tried but no dice. Thanks for the suggestion.
Have you tried out the @ConstructorProperties annotation? Jackson 2.9.4 should be able to make use of that:
@RequiredArgsConstructor(onConstructor = @__({@ConstructorProperties({"id"})}))
@JsonCreator should work too, I think.
Op 16 mrt. 2018 23:28 schreef "Máté Szabó" notifications@github.com:
Have you tried out the @ConstructorProperties annotation? Jackson 2.9.4
should be able to make use of that:@RequiredArgsConstructor(onConstructor = @__({@ConstructorProperties({"id"})}))
—
You are receiving this because you commented.
Reply to this email directly, view it on GitHub
https://github.com/rzwitserloot/lombok/issues/1612#issuecomment-373861993,
or mute the thread
https://github.com/notifications/unsubscribe-auth/AAKCRRrkgYXu7YaITEFY5tz6-iwWF3gPks5tfDykgaJpZM4SsgNP
.
Similar problem with spring boot upgrade 1.5.8 -> 2.0.0
The behavior of creating classes has changed
Class example:
@Data
@JsonInclude(JsonInclude.Include.NON_NULL)
public class A {
@JsonProperty("id")
private final long id;
}
Parsing json string:
A item = new ObjectMapper().readValue("{'id' : 10}", A.class);
Lombok 1.16.18 + Jackson 2.8.10 - _OK_
Lombok 1.16.20 + Jackson 2.9.4 - _Cannot construct instance of A (although at least one Creator exists): cannot deserialize from Object value (no delegate- or property-based Creator)_
i have the same problem when i migrated to v = 1.16.20.
java.lang.RuntimeException: com.fasterxml.jackson.databind.JsonMappingException: Can not construct instance of xx.xxx.xxx.Actions: no suitable constructor found, can not deserialize from Object value (missing default constructor or creator, or perhaps need to add/enable type information?)
but it works if i add the followings to lombok.config file:
lombok.anyConstructor.addConstructorProperties=true
config.stopBubbling = true
As @mcherb menioned, in lombok.config you can add:
lombok.anyConstructor.addConstructorProperties=true
This is also mentioned in the changelog.
Is this still an issue?
Yes
@chandresh-pancholi Can you explain how adding lombok.anyConstructor.addConstructorProperties=true to your lombok.config does not solve your problem?
Since v1.18.8 lombok added better understanding of @JsonProperty and @JsonSetter
Using @Value does not copy the @JsonProperty annotation on the constructor fields, however destructuring @Value has the intended behavior i.e. to copy the @JsonProperty on the constructor.
Here's the setup
lombok.config :config.stopBubbling = true
lombok.addLombokGeneratedAnnotation = true
# https://github.com/rzwitserloot/lombok/issues/1563
# due to JDK9 compatibility lombok introduced a breaking change by removing the
# java.beans.ConstrustorProperties (because it belongs to java.desktop) from the
# generated constructors, the issue indicate one shoud add the following property
#
# lombok.anyConstructor.addConstructorProperties = true
#
# however it will still require anyone to import java.desktop, which is not
# what we want for a server. The issue can be avoided if the code uses a
# constructor compiled with the -parameters option which is the case here.
# So it is possible to keep this option to false.
#
# However jackson had special understanding of the ConstructorProperties for his
# dynamic way to guess how to instanciate some classes. Without this jackson failed
# to find the constructor, so some classes needed a small help by adding the @JsonCreator
# or add @JsonProperty on the constructor parameter (this issue helped me in the matter
# https://github.com/FasterXML/jackson-databind/issues/1318)
lombok.copyableAnnotations += com.fasterxml.jackson.annotation.JsonFormat
Adding lombok.copyableAnnotations += com.fasterxml.jackson.annotation.JsonProperty has no effect.
Deserialisation of {"apple_token":"token"} by new ObjectMapper().readValue(content, AppleToken.class);
Java 11
Using
@Value only ❌
@Value
public class AppleToken {
@JsonProperty("apple_token")
String appleToken;
}
public final class AppleToken {
@JsonProperty("apple_token")
private final String appleToken;
@Generated
public AppleToken(final String appleToken) {
this.appleToken = appleToken;
}
@Generated
public String getAppleToken() {
return this.appleToken;
}
@Generated
public boolean equals(final Object o) {
if (o == this) {
return true;
} else if (!(o instanceof AppleToken)) {
return false;
} else {
AppleToken other = (AppleToken)o;
Object this$appleToken = this.getAppleToken();
Object other$appleToken = other.getAppleToken();
if (this$appleToken == null) {
if (other$appleToken != null) {
return false;
}
} else if (!this$appleToken.equals(other$appleToken)) {
return false;
}
return true;
}
}
@Generated
public int hashCode() {
int PRIME = true;
int result = 1;
Object $appleToken = this.getAppleToken();
int result = result * 59 + ($appleToken == null ? 43 : $appleToken.hashCode());
return result;
}
@Generated
public String toString() {
return "AppleToken(appleToken=" + this.getAppleToken() + ")";
}
}
adding
@JSonCreator(mode = Mode.PROPERTIES) on the constructor ❌
@Value
@AllArgsConstructor(onConstructor = @__(@JsonCreator(mode = Mode.PROPERTIES)))
public class AppleToken {
@JsonProperty("apple_token")
public final String appleToken;
}
public final class AppleToken {
@JsonProperty("apple_token")
private final String appleToken;
@Generated
public String getAppleToken() {
return this.appleToken;
}
@Generated
public boolean equals(final Object o) {
if (o == this) {
return true;
} else if (!(o instanceof AppleToken)) {
return false;
} else {
AppleToken other = (AppleToken)o;
Object this$appleToken = this.getAppleToken();
Object other$appleToken = other.getAppleToken();
if (this$appleToken == null) {
if (other$appleToken != null) {
return false;
}
} else if (!this$appleToken.equals(other$appleToken)) {
return false;
}
return true;
}
}
@Generated
public int hashCode() {
int PRIME = true;
int result = 1;
Object $appleToken = this.getAppleToken();
int result = result * 59 + ($appleToken == null ? 43 : $appleToken.hashCode());
return result;
}
@Generated
public String toString() {
return "AppleToken(appleToken=" + this.getAppleToken() + ")";
}
@JsonCreator(
mode = Mode.PROPERTIES
)
@Generated
public AppleToken(final String appleToken) {
this.appleToken = appleToken;
}
}
Destructuring
@Value ✅
@Getter
@FieldDefaults(makeFinal=true, level= AccessLevel.PRIVATE)
@EqualsAndHashCode
@ToString
@AllArgsConstructor
public class AppleToken {
@JsonProperty("apple_token")
String appleToken;
}
public class AppleToken {
@JsonProperty("apple_token")
String appleToken;
@JsonProperty("apple_token")
@Generated
public String getAppleToken() {
return this.appleToken;
}
@Generated
public boolean equals(final Object o) {
if (o == this) {
return true;
} else if (!(o instanceof AppleToken)) {
return false;
} else {
AppleToken other = (AppleToken)o;
if (!other.canEqual(this)) {
return false;
} else {
Object this$appleToken = this.getAppleToken();
Object other$appleToken = other.getAppleToken();
if (this$appleToken == null) {
if (other$appleToken != null) {
return false;
}
} else if (!this$appleToken.equals(other$appleToken)) {
return false;
}
return true;
}
}
}
@Generated
protected boolean canEqual(final Object other) {
return other instanceof AppleToken;
}
@Generated
public int hashCode() {
int PRIME = true;
int result = 1;
Object $appleToken = this.getAppleToken();
int result = result * 59 + ($appleToken == null ? 43 : $appleToken.hashCode());
return result;
}
@Generated
public String toString() {
return "AppleToken(appleToken=" + this.getAppleToken() + ")";
}
@Generated
public AppleToken(@JsonProperty("apple_token") final String appleToken) {
this.appleToken = appleToken;
}
}
Destructuring
@Value, with public final field and without getter ✅
//@Value
@FieldDefaults(makeFinal=true, level= AccessLevel.PUBLIC)
@EqualsAndHashCode
@ToString
@AllArgsConstructor
public class AppleToken {
@JsonProperty("apple_token")
String appleToken;
}
public class AppleToken {
@JsonProperty("apple_token")
public final String appleToken;
@Generated
public boolean equals(final Object o) {
if (o == this) {
return true;
} else if (!(o instanceof AppleToken)) {
return false;
} else {
AppleToken other = (AppleToken)o;
if (!other.canEqual(this)) {
return false;
} else {
Object this$appleToken = this.appleToken;
Object other$appleToken = other.appleToken;
if (this$appleToken == null) {
if (other$appleToken != null) {
return false;
}
} else if (!this$appleToken.equals(other$appleToken)) {
return false;
}
return true;
}
}
}
@Generated
protected boolean canEqual(final Object other) {
return other instanceof AppleToken;
}
@Generated
public int hashCode() {
int PRIME = true;
int result = 1;
Object $appleToken = this.appleToken;
int result = result * 59 + ($appleToken == null ? 43 : $appleToken.hashCode());
return result;
}
@Generated
public String toString() {
return "AppleToken(appleToken=" + this.appleToken + ")";
}
@Generated
public AppleToken(@JsonProperty("apple_token") final String appleToken) {
this.appleToken = appleToken;
}
}
edit: I'm not sure but I may have been played by the gradle cache when toggling the lombok.config (adding lombok.copyableAnnotations += com.fasterxml.jackson.annotation.JsonProperty)
Most helpful comment
As @mcherb menioned, in
lombok.configyou can add:This is also mentioned in the changelog.