ObjectIdWithBuilder1496Test.java
package tools.jackson.databind.tofix;
import java.util.List;
import java.util.concurrent.ConcurrentHashMap;
import org.junit.jupiter.api.Test;
import com.fasterxml.jackson.annotation.JsonIdentityInfo;
import com.fasterxml.jackson.annotation.ObjectIdGenerators;
import tools.jackson.databind.*;
import tools.jackson.databind.annotation.JsonDeserialize;
import tools.jackson.databind.annotation.JsonPOJOBuilder;
import tools.jackson.databind.testutil.DatabindTestUtil;
import tools.jackson.databind.testutil.failure.JacksonTestFailureExpected;
import static org.junit.jupiter.api.Assertions.*;
class ObjectIdWithBuilder1496Test extends DatabindTestUtil {
@JsonIdentityInfo(generator = ObjectIdGenerators.PropertyGenerator.class, property = "id")
@JsonDeserialize(builder = POJOBuilder.class)
static class POJO {
private long id;
public long getId() {
return id;
}
private int var;
public int getVar() {
return var;
}
POJO(long id, int var) {
this.id = id;
this.var = var;
}
@Override
public String toString() {
return "id: " + id + ", var: " + var;
}
}
@JsonIdentityInfo(generator = ObjectIdGenerators.PropertyGenerator.class, property = "id")
@JsonPOJOBuilder(withPrefix = "", buildMethodName = "readFromCacheOrBuild")
static final class POJOBuilder {
// Standard builder stuff
private long id;
private int var;
public POJOBuilder id(long _id) {
id = _id;
return this;
}
public POJOBuilder var(int _var) {
var = _var;
return this;
}
public POJO build() {
return new POJO(id, var);
}
// Special build method for jackson deserializer that caches objects already deserialized
private final static ConcurrentHashMap<Long, POJO> cache = new ConcurrentHashMap<>();
public POJO readFromCacheOrBuild() {
POJO pojo = cache.get(id);
if (pojo == null) {
POJO newPojo = build();
pojo = cache.putIfAbsent(id, newPojo);
if (pojo == null) {
pojo = newPojo;
}
}
return pojo;
}
}
@JsonIdentityInfo(generator = ObjectIdGenerators.PropertyGenerator.class, property = "id")
@JsonDeserialize(builder = EntityBuilder.class)
static class Entity
{
private long id;
private Entity ref;
private List<Entity> refs;
Entity(long id, Entity ref, List<Entity> refs) {
this.id = id;
this.ref = ref;
this.refs = refs;
}
public long getId() { return id; }
public Entity getRef() { return ref; }
public List<Entity> getRefs() { return refs; }
}
@JsonPOJOBuilder(withPrefix = "")
static class EntityBuilder
{
private long id;
private Entity ref;
private List<Entity> refs;
public EntityBuilder id(long id) { this.id = id; return this; }
public EntityBuilder ref(Entity ref) { this.ref = ref; return this; }
public EntityBuilder refs(List<Entity> refs) { this.refs = refs; return this; }
public Entity build() {
return new Entity(id, ref, refs);
}
}
static class EntityContainer
{
public List<Entity> entities;
}
private final ObjectMapper MAPPER = newJsonMapper();
/*
/**********************************************************************
/* Test cases
/**********************************************************************
*/
@JacksonTestFailureExpected
@Test
void builderId1496() throws Exception {
POJO input = new POJOBuilder().id(123L).var(456).build();
String json = MAPPER.writeValueAsString(input);
POJO result = MAPPER.readValue(json, POJO.class);
assertNotNull(result);
}
// Forward reference: first entity references second entity (which comes later)
@JacksonTestFailureExpected
@Test
public void testForwardReference() throws Exception
{
String json = a2q("{'entities':["
+ "{'id':1,'ref':2,'refs':[]},"
+ "{'id':2,'refs':[1]}"
+ "]}");
EntityContainer container = MAPPER.readValue(json, EntityContainer.class);
assertNotNull(container);
assertEquals(2, container.entities.size());
Entity first = container.entities.get(0);
Entity second = container.entities.get(1);
assertEquals(1, first.getId());
assertEquals(2, second.getId());
// first.ref -> second (forward reference)
assertSame(second, first.getRef());
// second.refs[0] -> first (back reference in collection)
assertEquals(1, second.getRefs().size());
assertSame(first, second.getRefs().get(0));
}
// Back reference: second entity references first entity (which came earlier)
@JacksonTestFailureExpected
@Test
public void testBackReference() throws Exception
{
String json = a2q("{'entities':["
+ "{'id':1,'refs':[2]},"
+ "{'id':2,'ref':1,'refs':[]}"
+ "]}");
EntityContainer container = MAPPER.readValue(json, EntityContainer.class);
assertNotNull(container);
assertEquals(2, container.entities.size());
Entity first = container.entities.get(0);
Entity second = container.entities.get(1);
assertEquals(1, first.getId());
assertEquals(2, second.getId());
// second.ref -> first (back reference)
assertSame(first, second.getRef());
// first.refs[0] -> second (forward reference in collection)
assertEquals(1, first.getRefs().size());
assertSame(second, first.getRefs().get(0));
}
}