ObjectIdWithDelegatingCreator1706Test.java
package tools.jackson.databind.objectid;
import java.util.List;
import org.junit.jupiter.api.Test;
import com.fasterxml.jackson.annotation.*;
import tools.jackson.core.type.TypeReference;
import tools.jackson.databind.*;
import tools.jackson.databind.annotation.JsonDeserialize;
import tools.jackson.databind.annotation.JsonSerialize;
import tools.jackson.databind.testutil.DatabindTestUtil;
import static org.junit.jupiter.api.Assertions.*;
/**
* Test for [databind#1706]: {@code @JsonCreator(mode=DELEGATING)} not working
* properly with {@code @JsonIdentityInfo} when deserializing a collection
* containing back-references.
*/
public class ObjectIdWithDelegatingCreator1706Test extends DatabindTestUtil
{
@JsonSerialize(as = ImmutableItem.class)
@JsonDeserialize(as = ImmutableItem.class)
@JsonIdentityInfo(generator = ObjectIdGenerators.IntSequenceGenerator.class)
interface Item {
Integer getId();
String getName();
}
static class ImmutableItem implements Item {
private final Integer id;
private final String name;
ImmutableItem(Integer id, String name) {
this.id = id;
this.name = name;
}
@Override
public Integer getId() { return id; }
@Override
public String getName() { return name; }
@JsonCreator(mode = JsonCreator.Mode.DELEGATING)
static ImmutableItem fromJson(MutableItem json) {
return new ImmutableItem(json.id, json.name);
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
ImmutableItem that = (ImmutableItem) o;
return id.equals(that.id) && name.equals(that.name);
}
@Override
public int hashCode() {
return 31 * id.hashCode() + name.hashCode();
}
}
@JsonDeserialize
@JsonAutoDetect(fieldVisibility = JsonAutoDetect.Visibility.NONE)
static class MutableItem implements Item {
private String name;
private Integer id;
public void setId(Integer id) { this.id = id; }
public void setName(String name) { this.name = name; }
@Override
public String getName() { throw new UnsupportedOperationException(); }
@Override
public Integer getId() { throw new UnsupportedOperationException(); }
}
private final ObjectMapper MAPPER = newJsonMapper();
// [databind#1706]
@Test
public void testObjectIdWithDelegatingCreator() throws Exception
{
ImmutableItem item = new ImmutableItem(1, "test");
// Serialize: list with same item twice produces ObjectId back-reference
// e.g. [{"@id":1,"id":1,"name":"test"},1]
String json = MAPPER.writeValueAsString(java.util.Arrays.asList(item, item));
// Deserialize: back-reference should resolve to ImmutableItem, not MutableItem
List<Item> result = MAPPER.readValue(json, new TypeReference<List<Item>>() {});
assertEquals(2, result.size());
// Both items should be ImmutableItem (not MutableItem for the back-reference)
assertInstanceOf(ImmutableItem.class, result.get(0),
"First item should be ImmutableItem");
assertInstanceOf(ImmutableItem.class, result.get(1),
"Second item (back-reference) should be ImmutableItem, not intermediate MutableItem");
assertEquals(result.get(0), result.get(1));
}
}