jackson-databind
jackson-databind copied to clipboard
setter method interferes with (some) getter methods
Hello,
first of all, i'm not really that experienced with jackson, but I've been running into an issue and i see no way to solve it. So, i have a class named 'Member' (see code below). Each member has a name, color, displayname and much more (but this is unrelevant). Each of these can be get using getName(), getColor(), and getDisplayName(). Now, whenever i add the setName() function, it's not even being referenced in another class, the 'name' property will always return null. When i change the method name, like add a letter, or make it static, it'll work just fine. What also makes it works is adding a @JsonProperty annotation to the getter. Adding it to the String itself also doesnt do anything Now, this is also the case for the getColor(). I have tried adding JsonIgnore to the setter methods but this didn't work either Now, the weird part is that the getDisplayName() works fine even though it is the exact same structure.
I've asked for help from an experienced java developer, which also couldn't help me and i couldn't find anything on this issue. I'm kinda lost as of what to do
Version 2.13.3
Code:
private String color;
@JsonProperty("name") //doesnt do anything
private String name;
@JsonProperty("display_name")
private String display_name;
@JsonProperty("display_name") //this makes it work
public String getName(){
return name;
}
public String getColor(){
return color;
}
public String getDisplayName(){
return display_name;
}
@JsonIgnore
public void setName(String name){
this.name = name;
}
@JsonIgnore
public void setDisplayName(String name){
this.display_name = name;
}
@JsonIgnore
public void setColor (String color){
this.color = color;
}
```
Going forward,the proper channel for usage questions; would be either mailing list:
https://groups.google.com/g/jackson-user
or Gitter chat:
https://gitter.im/FasterXML/jackson-databind
as issue tracker is meant for reporting bugs and requesting new features.
But since you have added all this information here I will try to help.
The problem here is that I don't know what the problem is. Interferes how? What you are you trying to do? Could you show a piece of code to explain the problem (unit test)?
So, i'll use my full code to explain. Its mean for the Pluralkit api
package com.luwuna.PluralkitAPI.Models;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.luwuna.PluralkitAPI.Models.Privacy.MemberPrivacy;
import com.luwuna.PluralkitAPI.Models.Privacy.SystemPrivacy;
import com.luwuna.PluralkitAPI.PluralkitAPI;
import org.json.JSONObject;
import java.util.List;
import static com.luwuna.PluralkitAPI.PluralkitAPI.token;
@JsonInclude(JsonInclude.Include.NON_NULL)
public class Member {
@JsonIgnore
protected ObjectMapper mapper = new ObjectMapper();
private String id;
private String uuid;
@JsonProperty("system") //for some reason it's not recognising the system variable, so I have to force it
private String system;
private String color;
private String name;
@JsonProperty("display_name")
private String display_name;
private String birthday;
private String description;
private String tag;
private String pronouns;
@JsonProperty("avatar_url")
private String avatar_url;
private String banner;
private String created;
// @JsonProperty("proxy_tags")
private ProxyTag[] proxyTags;
private MemberPrivacy privacy;
@JsonProperty("keep_proxy")
private boolean keepproxy;
public Member(){}
public String getId(){
return id;
}
public String getUUID(){
return uuid;
}
@JsonProperty("name") // will interfere if not present
public String getName(){
return name;
}
@JsonProperty("description")
public String getDescription(){
return description;
}
@JsonProperty("tag")
public String getTag(){
return tag;
}
@JsonProperty("pronouns")
public String getPronouns(){
return pronouns;
}
@JsonProperty("avatar_url")
public String getAvatarUrl(){
return avatar_url;
}
@JsonProperty("banner")
public String getBanner(){
return banner;
}
// @JsonProperty("color")
public String getColor(){
return color;
}
@JsonProperty("created")
public String getCreated(){
return created;
}
@JsonProperty("display_name")
public String getDisplayName(){
return display_name;
}
@JsonProperty("proxy_tags")
public ProxyTag[] getProxyTags(){
return proxyTags;
}
@JsonProperty("birthday")
public String getBirthday(){
return birthday;
}
@JsonProperty("keep_proxy")
public boolean hasKeepProxyEnabled(){
return keepproxy;
}
@JsonProperty("system")
public String getSystemId(){
return system;
}
@JsonProperty("privacy")
public MemberPrivacy getPrivacy(){
return privacy;
}
@JsonIgnore
public void setName(String name){
if(name.length() > 100) throw new IllegalArgumentException("A displayname must be less than 100 characters long!");
this.name = name;
}
@JsonIgnore
public void setDisplayName(String name){
if(name.length() > 100) throw new IllegalArgumentException("A displayname must be less than 100 characters long!");
this.display_name = name;
}
@JsonIgnore
public void setColor (String color){
// if(hexColor.startsWith("#")) hexColor = hexColor.substring(1);
// this.color = color;
}
@JsonIgnore
public void setBirthday(String birthday){
if(!birthday.matches("^\\d{4}-(0[1-9]|1[0-2])-(0[1-9]|[12][0-9]|3[01])$")){
throw new IllegalArgumentException("A date must match the YYYY-MM-DD pattern!");
}
this.birthday = birthday;
}
@JsonIgnore
public void setBirthday(String birthday, boolean hideYear){
if(!birthday.matches("^\\d{4}-(0[1-9]|1[0-2])-(0[1-9]|[12][0-9]|3[01])$")&&!hideYear) {
throw new IllegalArgumentException("A date must match the YYYY-MM-DD pattern!");
}
if(!birthday.matches("^\\d{2}-(0[1-9]|[12][0-9]|3[01])$")&&hideYear){
throw new IllegalArgumentException("A date must match the MM-DD pattern!");
}
if(hideYear){
birthday = "0004-" + birthday; //Setting the year to 0004 hides the year
}
this.birthday = birthday;
}
@JsonIgnore
public void setAvatarUrl(String url){
this.avatar_url = url;
}
@JsonIgnore
public void setPronouns(String pronouns){
this.pronouns = pronouns;
}
@JsonIgnore
public void applyUpdates() {
if(token==null) throw new IllegalArgumentException("You need a token to perform system changes!");
PluralkitAPI api = new PluralkitAPI(token);
try {
String json = mapper.writeValueAsString(this);
api.updateSystem(this.id, json);
}catch (Exception e){
e.printStackTrace();
}
}
}
As you can see, the getColor() method has an @JSONProperty() that is commented out. If i run it like this, the 'color' field will return null. If i add it, the color field will return its color. It does this with getName() aswell, but not with getAvatarUrl(). I have tried notating the initializations of the strings, to no avail Please note that i am very inexperienced with jackson so it might be a little messy
@Wolvinny Unfortunately this is bit too big an example, but also lacking some necessary detail. I'd need a minimal version showing what is wrong. Not "xxx is null" kind of narrative but showing what JSON is read and what values are not expected. Ideally a unit test to show input, assertions of state.
Basically: if deserialization (read from JSON, set Java property) or serialization (write JSON from Java property) is behaving different from what you expect, outline that.
Saying "color
will return null" is not clear to me.
The format of the JSONObect read from can be found here (i marked the property that gives issues), and the (simplified) object that returns is this
{
"id":"ccyvi",
"uuid":"5be75c0c-799f-4fe5-af15-933ade9516e4",
"system":"vspls",
"name":"Test",
"display_name":"test",
"color":"00ff00", //<-------
"birthday":"2000-01-01",
"pronouns":"she/they",
"avatar_url":"test.png",
"banner":null,
"description":null,
"created":"2022-08-20T12:17:07.675818Z"
}
The expected output of using System.out.println(.getColor()) is '00ff00', but is 'null' if not annotated with the @JsonProperty(). I marked the 'color" key, but this also happens with the 'name', 'pronouns' and 'display_name' keys.
At this point I am not going to spend any time trying to piece together various disparate things: what is needed is an actual fully self-closed unit test with assertions. Not a textual description of this and that being done: but actual code that reads and writes json, with checks.
Labeling with need-test-case
to denote that.