Skip to content

Commit

Permalink
Fix #744
Browse files Browse the repository at this point in the history
  • Loading branch information
cowtowncoder committed Apr 2, 2015
1 parent 0ec81c0 commit 817a45a
Show file tree
Hide file tree
Showing 3 changed files with 104 additions and 5 deletions.
2 changes: 2 additions & 0 deletions release-notes/VERSION
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ Project: jackson-databind
2.5.3 (not yet released)

#742: Allow deserialization of `null` Object Id (missing already allowed)
#744: Custom deserializer with parent object update failing
(reported by migel@github)
#745: EnumDeserializer.deserializerForCreator fails when used to deserialize a Map key
(contributed by John M)

Expand Down
24 changes: 22 additions & 2 deletions src/main/java/com/fasterxml/jackson/databind/ObjectReader.java
Original file line number Diff line number Diff line change
Expand Up @@ -138,12 +138,14 @@ public class ObjectReader
*/

/**
* Root-level cached deserializers
* Root-level cached deserializers.
* Passed by {@link ObjectMapper}, shared with it.
*/
final protected ConcurrentHashMap<JavaType, JsonDeserializer<Object>> _rootDeserializers;

/**
* Cache for root names used when root-wrapping is enabled.
* Passed by {@link ObjectMapper}, shared with it.
*/
protected final RootNameLookup _rootNames;

Expand Down Expand Up @@ -1471,7 +1473,7 @@ protected JsonNode _bindAsTree(JsonParser jp) throws IOException
result = NullNode.instance;
} else {
DeserializationContext ctxt = createDeserializationContext(jp, _config);
JsonDeserializer<Object> deser = _findRootDeserializer(ctxt, JSON_NODE_TYPE);
JsonDeserializer<Object> deser = _findTreeDeserializer(ctxt);
if (_unwrapRoot) {
result = (JsonNode) _unwrapAndDeserialize(jp, ctxt, JSON_NODE_TYPE, deser);
} else {
Expand Down Expand Up @@ -1569,6 +1571,24 @@ protected JsonDeserializer<Object> _findRootDeserializer(DeserializationContext
return deser;
}

/**
* @since 2.6
*/
protected JsonDeserializer<Object> _findTreeDeserializer(DeserializationContext ctxt)
throws JsonMappingException
{
JsonDeserializer<Object> deser = _rootDeserializers.get(JSON_NODE_TYPE);
if (deser == null) {
// Nope: need to ask provider to resolve it
deser = ctxt.findRootValueDeserializer(JSON_NODE_TYPE);
if (deser == null) { // can this happen?
throw new JsonMappingException("Can not find a deserializer for type "+JSON_NODE_TYPE);
}
_rootDeserializers.put(JSON_NODE_TYPE, deser);
}
return deser;
}

/**
* Method called to locate deserializer ahead of time, if permitted
* by configuration. Method also is NOT to throw an exception if
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
package com.fasterxml.jackson.databind.convert;

import java.io.IOException;
import java.util.*;

import com.fasterxml.jackson.annotation.JsonView;
import com.fasterxml.jackson.databind.BaseMapTest;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.core.*;
import com.fasterxml.jackson.databind.*;
import com.fasterxml.jackson.databind.deser.std.StdDeserializer;
import com.fasterxml.jackson.databind.module.SimpleModule;

import static org.junit.Assert.assertArrayEquals;

Expand Down Expand Up @@ -44,7 +47,40 @@ public class Updateable {
@JsonView(TextView.class)
public String str;
}


// for [databind#744]
static class DataA {
public int i = 1;
public int j = 2;

}

static class DataB {
public DataA da = new DataA();
public int k = 3;
}

static class DataADeserializer extends StdDeserializer<DataA> {
private static final long serialVersionUID = 1L;

DataADeserializer() {
super(DataA.class);
}

public DataA deserialize(JsonParser jp, DeserializationContext ctxt)
throws JsonProcessingException, IOException {
if (jp.getCurrentToken() != JsonToken.START_OBJECT) {
throw ctxt.mappingException("Wrong current token, expected START_OBJECT, got: "
+jp.getCurrentToken());
}
/*JsonNode node =*/ jp.readValueAsTree();

DataA da = new DataA();
da.i = 5;
return da;
}
}

/*
/********************************************************
/* Unit tests
Expand Down Expand Up @@ -146,4 +182,45 @@ public void testUpdatingWithViews() throws Exception
assertEquals(100, bean.num);
assertEquals("foobar", bean.str);
}

// [databind#744]
public void testIssue744() throws IOException
{
ObjectMapper mapper = new ObjectMapper();
SimpleModule module = new SimpleModule();
module.addDeserializer(DataA.class, new DataADeserializer());
mapper.registerModule(module);

DataB db = new DataB();
db.da.i = 11;
db.k = 13;
String jsonBString = mapper.writeValueAsString(db);
JsonNode jsonBNode = mapper.valueToTree(db);

// create parent
DataB dbNewViaString = mapper.readValue(jsonBString, DataB.class);
assertEquals(5, dbNewViaString.da.i);
assertEquals(13, dbNewViaString.k);

DataB dbNewViaNode = mapper.treeToValue(jsonBNode, DataB.class);
assertEquals(5, dbNewViaNode.da.i);
assertEquals(13, dbNewViaNode.k);

// update parent
DataB dbUpdViaString = new DataB();
DataB dbUpdViaNode = new DataB();

assertEquals(1, dbUpdViaString.da.i);
assertEquals(3, dbUpdViaString.k);
mapper.readerForUpdating(dbUpdViaString).readValue(jsonBString);
assertEquals(5, dbUpdViaString.da.i);
assertEquals(13, dbUpdViaString.k);

assertEquals(1, dbUpdViaNode.da.i);
assertEquals(3, dbUpdViaNode.k);

mapper.readerForUpdating(dbUpdViaNode).readValue(jsonBNode);
assertEquals(5, dbUpdViaNode.da.i);
assertEquals(13, dbUpdViaNode.k);
}
}

0 comments on commit 817a45a

Please sign in to comment.