22

I'm using lombok in my project and generation Setters and Getters using @Setters and @Getters annotations on top of POJO class. I'm trying to override setters method of a property but it's not working

I want to check if JSON property is Empty or Null i want to set default value in Setter method

@Setter
@Getter
@NoArgsConstructor
@AllArgsConstructor
@Accessors(chain = true)
@ToString
public class DefaultModel {


private String name;
@Setter(AccessLevel.NONE)private String age;    

public void setAge(String age) {
     if(age==null||age.trim().isEmpty()||age.equals("null")) {
        this.age="10";
    }else {
        this.age=age;
    }
}

}

Working scenarios:

        {
"name":"some",
"age":null
     }

     {
"name":"some",
"age":"null"
     }

    {
"name":"some",
"age":"  "
     }

Failed Scenario :

    {
"name":"some"
    }

Output:

DefaultModel(name=some, age=null)

And i'm following this as reference also here, but no luck so far

Ryuzaki L
  • 37,302
  • 12
  • 68
  • 98
  • 1
    Unrelated: maybe you check `age` to be != null **before** you call `isEmpty()` on it ... – GhostCat Jul 17 '18 at 19:02
  • 1
    Also unrelated: why is your `age` attribute a `String`? – Turing85 Jul 17 '18 at 19:03
  • Not so unrelated: `age.equals(null)` - this test will either return `false` or throw a `NullPointerException` (this is related to @GhostCat 's comment). – Turing85 Jul 17 '18 at 19:07
  • @GhostCat Lombok does dark magic in form of undocumented compiler-API calls. As far as I know, they work on the AST, but I do not know whether they delete existing nodes (e.g. existing setters). – Turing85 Jul 17 '18 at 19:11
  • but really this is all insane, how about if i use lombok getters and setters variable level, i mean deleting on top of class and declare on each variable if required? – Ryuzaki L Jul 17 '18 at 19:16
  • @Deadpool do you ever set the name in the failed scenario? If so how? – lealceldeiro Jul 17 '18 at 19:32
  • 1
    Unrelated: You should use `@Data` instead of annotating with `@Getter` and `@Setter`. @Data is a shortcut for those and includes `@ToString` and `@EqualsAndHashCode`. – shimatai Jul 17 '18 at 20:34

2 Answers2

28

Either you just hit a bug I've never seen or you're testing it wrong.

An annotation like

@Setter(AccessLevel.NONE) private String age;

on the field level indeed stops the setter from being generated. But given that you're defining a setter, you don't even need it. An explicit @Setter stops the generation, too.

I've just tried your example using Eclipse 4.7.3a and Lombok 1.18.0 and your (buggy) setter gets called. I've been using Lombok a lot over a few years and never encountered such a bug.

Most probably the problem is that your JSON deserializer does not use setters at all. I guess, you're testing something like

DefaultModel defaultModel = deserialize("{\"name\":\"some\"}", DefaultModel.class);

instead of testing the setter directly. And that's the problem.

maaartinus
  • 44,714
  • 32
  • 161
  • 320
  • @Deadpool No idea how postman works, but I'd bet it uses no setters. GSON doesn't use them either. – maaartinus Jul 17 '18 at 20:30
  • @maaartinus agree with you, That's why asked @Deadpool (OP) if he/she ever set the name in the failed scenario (call the setter)... because I [**tested**](https://github.com/lealceldeiro/settertest) it too and it works the thing with the `null` is a serialization/deserialization issue, not related at all with loombok. – lealceldeiro Jul 17 '18 at 21:28
  • Thanks for the clarification, i agree with you it's problem with deserialization of missing fields in JSON body – Ryuzaki L Jul 17 '18 at 21:42
0

It possible that JSON deserializer uses constructor generated by Lombok (not setters).

Have a look here: Jackson deserialize default values missing

tomikmar
  • 131
  • 2
  • 6