FasterXML / FasterXML/jackson-databind
Two Type fields in serialised string, when using using `As.EXTERNAL_PROPERTY` with `@JsonTypeName`
- Dominant language
- Java
- Stars
- 3.7k
- Forks
- 1.5k
- Avg merge
- 3d 6h
- Merged PRs (30d)
- 28
Description
**Describe the bug**
I have a class with `@JsonTypeName` which uses the external field `type`, I also have a `type` field in my class. When I am serializing the class object, I am getting two type values.
I have checked that there are issues similar to this issue, but those issues are for `PROPERTY` and not `EXTERNAL_PROPERTY`.
**Version information**
Jackson version: 2.7.9
**To Reproduce**
I have an interface `AnimalDetails` which is deserialized based on an external property `type`.
```
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonTypeInfo;
@JsonIgnoreProperties(ignoreUnknown = true)
@JsonTypeInfo(
use = JsonTypeInfo.Id.NAME, property = "type", include = JsonTypeInfo.As.EXTERNAL_PROPERTY, visible = true)
public abstract class AnimalDetails {
}
```
I have a subclass `Dog` of class `AnimalDetails`
```
package io.harness.connector.jacksonTest;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonIgnoreType;
import com.fasterxml.jackson.annotation.JsonTypeName;
@JsonIgnoreProperties(ignoreUnknown = true)
@JsonTypeName("dog")
public class Dog extends AnimalDetails{
String type;
public Dog(String type){
this.type = type;
}
public Dog() {
}
public static DogBuilder builder() {
return new DogBuilder();
}
public String getType() {
return this.type;
}
public void setType(String type) {
this.type = type;
}
public boolean equals(final Object o) {
if (o == this) return true;
if (!(o instanceof Dog)) return false;
final Dog other = (Dog) o;
if (!other.canEqual((Object) this)) return false;
final Object this$type = this.getType();
final Object other$type = other.getType();
if (this$type == null ? other$type != null : !this$type.equals(other$type)) return false;
return true;
}
protected boolean canEqual(final Object other) {
return other instanceof Dog;
}
public int hashCode() {
final int PRIME = 59;
int result = 1;
final Object $type = this.getType();
result = result * PRIME + ($type == null ? 43 : $type.hashCode());
return result;
}
public String toString() {
return "Dog(type=" + this.getType() + ")";
}
public static class DogBuilder {
private String type;
DogBuilder() {
}
public Dog.DogBuilder type(String type) {
this.type = type;
return this;
}
public Dog build() {
return new Dog(type);
}
public String toString() {
return "Dog.DogBuilder(type=" + this.type + ")";
}
}
}
```
The dog also contains a field `type` and I have used `JsonTypeName` annotation to say that deserialize into a Dog when the external `type` is "dog".
When I am trying to serialize the `Dog` class then I get two `type` fields.
```
package io.harness.connector.jacksonTest;
import com.fasterxml.jackson.databind.ObjectMapper;
import io.harness.ng.remote.NGObjectMapperHelper;
import org.slf4j.Logger;
class Scratch {
private static final Logger logger = org.slf4j.LoggerFactory.getLogger(Scratch.class);
public static void main(String[] args) {
Dog dog = Dog.builder().type("GermanShepherd").build();
ObjectMapper objectMapper = new ObjectMapper();
NGObjectMapperHelper.configureNGObjectMapper(objectMapper);
String jsonValue = "";
try {
jsonValue = objectMapper.writeValueAsString(dog);
}catch(Exception ex){
logger.info("Encountered exception ", ex);
}
logger.info(jsonValue);
}
}
```
**Expected behavior**
Output: {"type":"dog","type":"GermanShepherd"}
ExpectedOutupt: {"type":"GermanShepherd"}
**Additional context**
Contributor guide
No contributing guide indexed for this repository
Assessment
This issue has not been assessed yet.