1717import org .junit .jupiter .api .Test ;
1818
1919import static org .junit .jupiter .api .Assertions .assertEquals ;
20+ import static org .junit .jupiter .api .Assertions .assertNull ;
2021import static org .junit .jupiter .api .Assertions .fail ;
2122
2223// [databind#562] Allow @JsonAnySetter on Creator constructors
@@ -36,13 +37,29 @@ public POJO562(@JsonProperty("a") String a,
3637 }
3738 }
3839
40+ static class POJO562WithAnnotationOnBothCtorParamAndField
41+ {
42+ String a ;
43+ @ JsonAnySetter
44+ Map <String ,Object > stuffFromField ;
45+ Map <String ,Object > stuffFromConstructor ;
46+
47+ @ JsonCreator
48+ public POJO562WithAnnotationOnBothCtorParamAndField (@ JsonProperty ("a" ) String a ,
49+ @ JsonAnySetter Map <String , Object > leftovers
50+ ) {
51+ this .a = a ;
52+ stuffFromConstructor = leftovers ;
53+ }
54+ }
55+
3956 static class POJO562WithField
4057 {
4158 String a ;
4259 Map <String ,Object > stuff ;
4360
4461 public String b ;
45-
62+
4663 @ JsonCreator
4764 public POJO562WithField (@ JsonProperty ("a" ) String a ,
4865 @ JsonAnySetter Map <String , Object > leftovers
@@ -115,12 +132,32 @@ public void mapAnySetterViaCreator562() throws Exception
115132
116133 assertEquals ("value" , pojo .a );
117134 assertEquals (expected , pojo .stuff );
118-
135+
119136 // Should also initialize any-setter-Map even if no contents
120137 pojo = MAPPER .readValue (a2q ("{'a':'value2'}" ), POJO562 .class );
121138 assertEquals ("value2" , pojo .a );
122139 assertEquals (new HashMap <>(), pojo .stuff );
140+ }
123141
142+ // [databind#4634]
143+ @ Test
144+ public void mapAnySetterViaCreatorWhenBothCreatorAndFieldAreAnnotated () throws Exception
145+ {
146+ Map <String , Object > expected = new HashMap <>();
147+ expected .put ("b" , Integer .valueOf (42 ));
148+ expected .put ("c" , Integer .valueOf (111 ));
149+
150+ POJO562WithAnnotationOnBothCtorParamAndField pojo = MAPPER .readValue (a2q (
151+ "{'a':'value', 'b':42, 'c': 111}"
152+ ),
153+ POJO562WithAnnotationOnBothCtorParamAndField .class );
154+
155+ assertEquals ("value" , pojo .a );
156+ assertEquals (expected , pojo .stuffFromConstructor );
157+ // In an ideal world, maybe exception should be thrown for annotating both field + constructor parameter,
158+ // but that scenario is possible in this imperfect world e.g. annotating `@JsonAnySetter` on a Record component
159+ // will cause that annotation to be (auto)propagated to both the field & constructor parameter (& accessor method)
160+ assertNull (pojo .stuffFromField );
124161 }
125162
126163 // Creator and non-Creator props AND any-setter ought to be fine too
0 commit comments