2
2
3
3
import java .util .LinkedHashMap ;
4
4
import java .util .Map ;
5
+ import java .util .concurrent .atomic .AtomicInteger ;
5
6
6
7
import com .fasterxml .jackson .annotation .*;
7
8
@@ -59,6 +60,25 @@ static class BrokenBean {
59
60
public BrokenBean (String v ) { value = v ; }
60
61
}
61
62
63
+ // [databind#3481]
64
+ static class CountingFooFilter {
65
+ public final static AtomicInteger counter = new AtomicInteger (0 );
66
+
67
+ @ Override
68
+ public boolean equals (Object other ) {
69
+ counter .incrementAndGet ();
70
+ return "foo" .equals (other );
71
+ }
72
+ }
73
+
74
+ static class CountingFooBean {
75
+ @ JsonInclude (value =JsonInclude .Include .CUSTOM ,
76
+ valueFilter =CountingFooFilter .class )
77
+ public String value ;
78
+
79
+ public CountingFooBean (String v ) { value = v ; }
80
+ }
81
+
62
82
/*
63
83
/**********************************************************
64
84
/* Test methods, success
@@ -79,10 +99,27 @@ public void testCustomFilterWithMap() throws Exception
79
99
.add ("a" , "1" )
80
100
.add ("b" , "foo" )
81
101
.add ("c" , "2" );
82
-
102
+
83
103
assertEquals (a2q ("{'stuff':{'a':'1','c':'2'}}" ), MAPPER .writeValueAsString (input ));
84
104
}
85
105
106
+ // [databind#3481]
107
+ public void testRepeatedCalls () throws Exception
108
+ {
109
+ CountingFooFilter .counter .set (0 );
110
+
111
+ assertEquals (a2q ("{'value':'x'}" ),
112
+ MAPPER .writeValueAsString (new CountingFooBean ("x" )));
113
+
114
+ // 06-May-2022, tatu: Maybe surprisingly, we get TWO calls; first one to
115
+ // see if `null`s are to be filtered, second time for "real" call
116
+ assertEquals (2 , CountingFooFilter .counter .get ());
117
+ assertEquals ("{}" , MAPPER .writeValueAsString (new CountingFooBean ("foo" )));
118
+
119
+ // but beyond initial extra call, as expected
120
+ assertEquals (3 , CountingFooFilter .counter .get ());
121
+ }
122
+
86
123
/*
87
124
/**********************************************************
88
125
/* Test methods, fail handling
0 commit comments