-
-
Notifications
You must be signed in to change notification settings - Fork 1.4k
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
Support for non-scalar ObjectId Reference deserialiazation #622
Comments
One way to get bit further with this would be to write a unit test that shows how things should work; and I can have a look to see what is needed to make it work. |
Maybe the test on JSOG project ? |
That sounds like a good start, sure. |
If there is anything specific I can do to help, let me know. The activity around this is good timing - JSOG deserialization in Java just became an issue in a project I'm working on. |
Hmmh. I take it back; amount of code needed to cut'n paste is non-trivial, so I more self-contained test would probably be needed. I am also unlikely to have time to work on this myself, although can try to help as usual. |
Addendum to the preceding comment: while I may not have time to spearhead this, I concur that timing for getting support in for 2.5 is good now. And @stickfigure definitely knows a lot about this area. |
I wish I could help but I don't know where to start. Should the test look more like testCustomPoolResolver or testCustomDeserializationClass ? or am I off track ? Please excuse my ignorance. |
I think it's fine to start with that code, and try to make code minimal. Could probably drop serialization code and just use hard-coded JSON (that may be generated with serializer). |
I hope this is concise enough. package com.jackson.jsog;
import java.io.IOException;
import org.testng.annotations.Test;
import com.fasterxml.jackson.annotation.JsonIdentityInfo;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.annotation.ObjectIdGenerator;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JsonDeserializer;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
public class JSOGDeserializeTest {
/** the key of the property that holds the ref */
public static final String REF_KEY = "@ref";
/**
* JSON input
*/
private static final String EXP_EXAMPLE_JSOG = "{\"@id\":\"1\",\"foo\":66,\"next\":{\"@ref\":\"1\"}}";
ObjectMapper mapper = new ObjectMapper();
/**
* Customer IdGenerator
*/
static class JSOGGenerator extends ObjectIdGenerator<JSOGRef> {
private static final long serialVersionUID = 1L;
protected transient int _nextValue;
protected final Class<?> _scope;
protected JSOGGenerator() { this(null, -1); }
protected JSOGGenerator(Class<?> scope, int nextValue) {
_scope = scope;
_nextValue = nextValue;
}
@Override
public Class<?> getScope() {
return _scope;
}
@Override
public boolean canUseFor(ObjectIdGenerator<?> gen) {
return (gen.getClass() == getClass()) && (gen.getScope() == _scope);
}
@Override
public ObjectIdGenerator<JSOGRef> forScope(Class<?> scope) {
return (_scope == scope) ? this : new JSOGGenerator(scope, _nextValue);
}
@Override
public ObjectIdGenerator<JSOGRef> newForSerialization(Object context) {
return new JSOGGenerator(_scope, 1);
}
@Override
public com.fasterxml.jackson.annotation.ObjectIdGenerator.IdKey key(Object key) {
return new IdKey(getClass(), _scope, key);
}
@Override
public JSOGRef generateId(Object forPojo) {
int id = _nextValue;
++_nextValue;
return new JSOGRef(id);
}
}
/**
* The reference deserializer
*/
static class JSOGRefDeserializer extends JsonDeserializer<JSOGRef>
{
@Override
public JSOGRef deserialize(JsonParser jp, DeserializationContext ctx) throws IOException, JsonProcessingException {
JsonNode node = jp.readValueAsTree();
if (node.isTextual()) {
return new JSOGRef(node.asInt());
} else {
return new JSOGRef(node.get(REF_KEY).asInt());
}
}
}
/**
* The reference object
*/
@JsonDeserialize(using=JSOGRefDeserializer.class)
static class JSOGRef
{
@JsonProperty(REF_KEY)
public int ref;
public JSOGRef() {
}
public JSOGRef(int val) {
ref = val;
}
}
/**
* Example class using JSOGGenerator
*/
@JsonIdentityInfo(generator=JSOGGenerator.class)
public static class IdentifiableExampleJSOG {
public int foo;
public IdentifiableExampleJSOG next;
}
@Test
public void testStructJSOGRef() throws Exception {
// Because the value ({@ref:1}) is not scalar, parser thinks it is not an id
// and tries to deserialize as normal a new IdentifiableExampleJSOG
// then complains about unrecognized field "@ref"
IdentifiableExampleJSOG result = mapper.readValue(EXP_EXAMPLE_JSOG, IdentifiableExampleJSOG.class);
assert 66 == result.foo;
assert result == result.next;
}
} |
Thanks, I think this'll work as starting point yes. |
…; id class MUST implement #equals() and #hashCode()!) Will see if polymorphic case would support, and if not, what is needed to support it.
Ok, some good news: after adding couple things, test now actually passes. Things to note:
I will add another test for polymorphic type case, but I am mildly optimistic that this will be solved for 2.5. |
The jackson-jsog code has been updated with this new contract and it works great! Thanks Tatu. Now just looking forward to the RC of 2.5! Also, I'd happily contribute this code to jackson for inclusion in a future version. |
I am using JSOG by @stickfigure which works beautifully for serialization, but there seems to be an issue with deserialiazation since only scalar values are supported for ObjectIds. It would really be helpfull if this could work.
Below are suggestions from Tatu on the user-list:
and
(*)I am not familiar with how jackson "does things", otherwise I would have translated the "it can claim that @JsonIdentityInfo was found" to code and this issue would not be :)
There is this comment on BeanDeserializerBase
Discussions on the user-list I have found :
https://groups.google.com/d/topic/jackson-user/4jf2E_FKOIk/discussion
And the initial one between Jeff and Tatu
http://markmail.org/message/n6vrh4zi5nm3r3wt#query:+page:1+mid:nxpbwkisautcjl7u+state:results
The text was updated successfully, but these errors were encountered: