-
-
Notifications
You must be signed in to change notification settings - Fork 1.4k
Test case for #3964 MismatchedInputException, Bean not yet resolved #3983
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,297 @@ | ||
| package com.fasterxml.jackson.failing; | ||
|
|
||
| import com.fasterxml.jackson.annotation.JsonBackReference; | ||
| import com.fasterxml.jackson.annotation.JsonCreator; | ||
| import com.fasterxml.jackson.annotation.JsonIdentityInfo; | ||
| import com.fasterxml.jackson.annotation.JsonProperty; | ||
| import com.fasterxml.jackson.annotation.ObjectIdGenerators; | ||
| import com.fasterxml.jackson.core.JsonProcessingException; | ||
| import com.fasterxml.jackson.databind.BaseMapTest; | ||
| import com.fasterxml.jackson.databind.DeserializationFeature; | ||
| import com.fasterxml.jackson.databind.ObjectMapper; | ||
| import com.fasterxml.jackson.databind.exc.MismatchedInputException; | ||
| import java.util.List; | ||
|
|
||
| // [databind#3964] MismatchedInputException, Bean not yet resolved | ||
| public class JsonIdentityInfoAndBackReferences3964Test extends BaseMapTest | ||
| { | ||
| /** | ||
| * Fails : Original test | ||
| */ | ||
| @JsonIdentityInfo( | ||
| generator = ObjectIdGenerators.PropertyGenerator.class, | ||
| property = "id", | ||
| scope = Tree.class | ||
| ) | ||
| public static class Tree { | ||
| private final int id; | ||
| private List<Fruit> fruits; | ||
|
|
||
| @JsonCreator | ||
| public Tree(@JsonProperty("id") int id, @JsonProperty("fruits") List<Fruit> fruits) { | ||
| this.id = id; | ||
| this.fruits = fruits; | ||
| } | ||
|
|
||
| public int getId() { | ||
| return id; | ||
| } | ||
|
|
||
| public List<Fruit> getFruits() { | ||
| return fruits; | ||
| } | ||
|
|
||
| public void setFruits(List<Fruit> fruits) { | ||
| this.fruits = fruits; | ||
| } | ||
| } | ||
|
|
||
| @JsonIdentityInfo( | ||
| generator = ObjectIdGenerators.PropertyGenerator.class, | ||
| property = "id", | ||
| scope = Fruit.class | ||
| ) | ||
| public static class Fruit { | ||
| private final int id; | ||
| private List<Calories> calories; | ||
| @JsonBackReference("id") | ||
| private Tree tree; | ||
|
|
||
| @JsonCreator | ||
| public Fruit(@JsonProperty("id") int id, @JsonProperty("calories") List<Calories> calories) { | ||
| this.id = id; | ||
| this.calories = calories; | ||
| } | ||
|
|
||
| public int getId() { | ||
| return id; | ||
| } | ||
|
|
||
| public Tree getTree() { | ||
| return tree; | ||
| } | ||
|
|
||
| public void setTree(Tree tree) { | ||
| this.tree = tree; | ||
| } | ||
|
|
||
| public List<Calories> getCalories() { | ||
| return calories; | ||
| } | ||
|
|
||
| public void setCalories(List<Calories> calories) { | ||
| this.calories = calories; | ||
| } | ||
| } | ||
|
|
||
| @JsonIdentityInfo( | ||
| generator = ObjectIdGenerators.PropertyGenerator.class, | ||
| property = "id", | ||
| scope = Calories.class | ||
| ) | ||
| public static class Calories { | ||
| private final int id; | ||
| private Fruit fruit; | ||
|
|
||
| @JsonCreator | ||
| public Calories(@JsonProperty("id") int id) { | ||
| this.id = id; | ||
| } | ||
|
|
||
| public int getId() { | ||
| return id; | ||
| } | ||
|
|
||
| public Fruit getFruit() { | ||
| return fruit; | ||
| } | ||
|
|
||
| public void setFruit(Fruit fruit) { | ||
| this.fruit = fruit; | ||
| } | ||
| } | ||
|
|
||
| /** | ||
| * Fails : Lean version that fails and Without getters and setters | ||
| */ | ||
| @JsonIdentityInfo( | ||
| generator = ObjectIdGenerators.PropertyGenerator.class, | ||
| property = "id", | ||
| scope = Animal.class | ||
| ) | ||
| public static class Animal { | ||
| public final int id; | ||
| public List<Cat> cats; | ||
|
|
||
| @JsonCreator | ||
| public Animal(@JsonProperty("id") int id, @JsonProperty("cats") List<Cat> cats) { | ||
| this.id = id; | ||
| this.cats = cats; | ||
| } | ||
| } | ||
|
|
||
| @JsonIdentityInfo( | ||
| generator = ObjectIdGenerators.PropertyGenerator.class, | ||
| property = "id", | ||
| scope = Cat.class | ||
| ) | ||
| public static class Cat { | ||
| public int id; | ||
| public List<Food> foods; | ||
| @JsonBackReference("id") | ||
| public Animal animal; | ||
|
|
||
| @JsonCreator | ||
| public Cat(@JsonProperty("id") int id, @JsonProperty("foods") List<Food> foods) { | ||
| this.id = id; | ||
| this.foods = foods; | ||
| } | ||
| } | ||
|
|
||
| @JsonIdentityInfo( | ||
| generator = ObjectIdGenerators.PropertyGenerator.class, | ||
| property = "id", | ||
| scope = Food.class | ||
| ) | ||
| public static class Food { | ||
| public int id; | ||
| public Cat cat; | ||
|
|
||
| @JsonCreator | ||
| public Food(@JsonProperty("id") int id) { | ||
| this.id = id; | ||
| } | ||
| } | ||
|
|
||
| /** | ||
| * Passes : Testing lean without getters and setters | ||
| * and also without {@link JsonCreator}. | ||
| */ | ||
| @JsonIdentityInfo( | ||
| generator = ObjectIdGenerators.PropertyGenerator.class, | ||
| property = "id", | ||
| scope = Fish.class | ||
| ) | ||
| public static class Fish { | ||
| public int id; | ||
| public List<Squid> squids; | ||
| } | ||
|
|
||
| @JsonIdentityInfo( | ||
| generator = ObjectIdGenerators.PropertyGenerator.class, | ||
| property = "id", | ||
| scope = Squid.class | ||
| ) | ||
| public static class Squid { | ||
| public int id; | ||
| public List<Shrimp> shrimps; | ||
| @JsonBackReference("id") | ||
| public Fish fish; | ||
| } | ||
|
|
||
| @JsonIdentityInfo( | ||
| generator = ObjectIdGenerators.PropertyGenerator.class, | ||
| property = "id", | ||
| scope = Shrimp.class | ||
| ) | ||
| public static class Shrimp { | ||
| public int id; | ||
| public Squid squid; | ||
| } | ||
|
|
||
| /* | ||
| /********************************************************************** | ||
| /* Test methods | ||
| /********************************************************************** | ||
| */ | ||
|
|
||
| final ObjectMapper MAPPER = jsonMapperBuilder() | ||
| .enable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES).build(); | ||
|
|
||
| /** | ||
| * Fails : Original test | ||
| */ | ||
| public void testOriginal() throws JsonProcessingException { | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Could you change this to just throw
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Sorry about this repeated forgetting to change to Exception repeatedly 🥲 I will find a mechanim to prevent this from happening 👍🏻👍🏻 |
||
| String json = "{" + | ||
| " \"id\": 1,\n" + | ||
| " \"fruits\": [\n" + | ||
| " {\n" + | ||
| " \"id\": 2,\n" + | ||
| " \"tree\": 1,\n" + | ||
| " \"calories\": [\n" + | ||
| " {\n" + | ||
| " \"id\": 3,\n" + | ||
| " \"fruit\": 2\n" + | ||
| " }\n" + | ||
| " ]\n" + | ||
| " }\n" + | ||
| " ]\n" + | ||
| " }"; | ||
|
|
||
| try { | ||
| Tree tree = MAPPER.readValue(json, Tree.class); | ||
| // should reach here and pass... but throws Exception and fails | ||
| assertEquals(tree, tree.fruits.get(0).tree); | ||
| } catch (MismatchedInputException e) { | ||
| verifyException(e, "Cannot resolve ObjectId forward reference using property 'animal'"); | ||
| verifyException(e, "Bean not yet resolved"); | ||
| fail("Should not reach"); | ||
| } | ||
| } | ||
|
|
||
| /** | ||
| * Fails : Lean version that fails and Without getters and setters | ||
| */ | ||
| public void testLeanWithoutGetterAndSetters() throws JsonProcessingException { | ||
| String json = a2q("{" + | ||
| " 'id': 1," + | ||
| " 'cats': [" + | ||
| " {" + | ||
| " 'id': 2," + | ||
| " 'animal': 1," + // reference here | ||
| " 'foods': [" + | ||
| " {" + | ||
| " 'id': 3," + | ||
| " 'cat': 2" + | ||
| " }" + | ||
| " ]" + | ||
| " }" + | ||
| " ]" + | ||
| " }"); | ||
|
|
||
| try { | ||
| Animal animal = MAPPER.readValue(json, Animal.class); | ||
| // should reach here and pass... but throws Exception and fails | ||
| assertEquals(animal, animal.cats.get(0).animal); | ||
| } catch (MismatchedInputException e) { | ||
| verifyException(e, "Cannot resolve ObjectId forward reference using property 'animal'"); | ||
| verifyException(e, "Bean not yet resolved"); | ||
| fail("Should not reach"); | ||
| } | ||
| } | ||
|
|
||
| /** | ||
| * Passes : Testing lean without getters and setters | ||
| * and also without {@link JsonCreator}. | ||
| */ | ||
| public void testLeanWithoutGetterAndSettersAndCreator() throws Exception { | ||
| String json = a2q("{" + | ||
| " 'id': 1," + | ||
| " 'squids': [" + | ||
| " {" + | ||
| " 'id': 2," + | ||
| " 'fish': 1," + // back reference | ||
| " 'shrimps': [" + | ||
| " {" + | ||
| " 'id': 3," + | ||
| " 'squid': 2" + | ||
| " }" + | ||
| " ]" + | ||
| " }" + | ||
| " ]" + | ||
| " }"); | ||
|
|
||
| Fish fish = MAPPER.readValue(json, Fish.class); | ||
| assertEquals(fish, fish.squids.get(0).fish); | ||
| } | ||
| } | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Here, below is test case.