I am using Jackson to de-serialize this class
import com.fasterxml.jackson.annotation.JsonSubTypes;
import com.fasterxml.jackson.annotation.JsonTypeInfo;
@JsonTypeInfo(use = JsonTypeInfo.Id.DEDUCTION)
@JsonSubTypes({
@JsonSubTypes.Type(value = DatiSocieta.class, name = "datiSocieta"),
@JsonSubTypes.Type(value = DatiPersonaFisica.class, name = "datiPersonaFisica") ,
@JsonSubTypes.Type(value = DatiDittaIndividuale.class, name = "datiDittaIndividuale") }
)
public interface Dati {
}
The problem is that datiPersonaFisica
and datiDittaIndividuale
are ambiguous
@Data
public
class DatiPersonaFisica implements Dati {
private String codiceFiscale;
private String sesso;
private String nome;
private String cognome;
@JsonFormat(pattern = "yyyy-MM-dd")
private Date dataNascita;
private String luogoNascita;
private String provinciaNascita;
private String nazioneNascita;
}
@Data
public
class DatiDittaIndividuale implements Dati {
private String denominazione;
private String codiceFiscale;
private String sesso;
private String nome;
private String cognome;
@JsonFormat(pattern = "yyyy-MM-dd")
private Date dataNascita;
private String luogoNascita;
private String provinciaNascita;
private String nazioneNascita;
private String numeroRea;
private String provinciaCCIA;
private String partitaIVA;
}
So it gives me the error
JSON parse error: Could not resolve subtype of [simple type, class com.XXXX.cmp.cgw.webclient.bo.Dati]: Cannot deduce unique subtype of
com.xxxx.cmp.cgw.webclient.bo.Dati
(2 candidates match); nested exception is com.fasterxml.jackson.databind.exc.InvalidTypeIdException: Could not resolve subtype of [simple type, class com.xxxx.cmp.cgw.webclient.bo.Dati]: Cannot deduce unique subtype ofcom.xxxx.cmp.cgw.webclient.bo.Dati
(2 candidates match)\n at [Source: (org.springframework.util.StreamUtils$NonClosingInputStream); line: 12, column: 5] (through reference chain: com.xxxx.cmp.cgw.webclient.dto.ClienteDTO["soggetto"]->com.xxxx.cmp.cgw.webclient.bo.Soggetto["anagrafica"])
I would like to auto-detect datiPersonaFisica
if the specific fields of datiDittaIndividuale
are missing. But I can't find how in the documentation.
The attributes in your DatiPersonaFisica
class are a subset of the ones in DatiDittaIndividuale
. If Jackson tries to deserialize a Json containing only the fields from DatiPersonaFisica
, it has no way to tell which instance to construct, as the Json matches the fingerprint of both of your classes. See the issue #3577 on the official Jackson-databind repository.
A Json constructed with only the fields from DatiPersonaFisica
may either be an instance of DatiPersonaFisica
, or an instance of DatiDittaIndividuale
whose only serialized fields are the ones in common with DatiPersonaFisica
; hence, the error message:
Cannot deduce unique subtype of com.xxxx.cmp.cgw.webclient.bo.Dati (2 candidates match)
In your case, since there is no way to tell which class is which with a DatiPersonaFisica
's Json, you could either go for an implementation with JsonTypeInfo.As.PROPERTY
or JsonTypeInfo.As.EXTERNAL_PROPERTY
as suggested in the issues' thread.
@JsonTypeInfo(
use = JsonTypeInfo.Id.NAME,
include = JsonTypeInfo.As.PROPERTY,
property = "datiType"
)
@JsonSubTypes({
@JsonSubTypes.Type(value = DatiSocieta.class, name = "datiSocieta"),
@JsonSubTypes.Type(value = DatiPersonaFisica.class, name = "datiPersonaFisica"),
@JsonSubTypes.Type(value = DatiDittaIndividuale.class, name = "datiDittaIndividuale")
})
public interface Dati {
}
@Data
public class DatiSocieta implements Dati {
// fields...
}
@Data
public class DatiPersonaFisica implements Dati {
// fields...
}
@Data
public class DatiDittaIndividuale implements Dati {
// fields...
}
Here is a demo at OneCompiler 1
@JsonTypeInfo(
use = JsonTypeInfo.Id.NAME,
include = JsonTypeInfo.As.EXTERNAL_PROPERTY,
property = "type"
)
@JsonSubTypes({
@JsonSubTypes.Type(value = DatiPersonaFisica.class, name = "DatiPersonaFisica"),
@JsonSubTypes.Type(value = DatiDittaIndividuale.class, name = "DatiDittaIndividuale")
})
public class Company {
protected Dati dati;
//constructors
//getters and setters
}
public class Dati {
private String nome;
private String cognome;
//constructors
//getters and setters
}
public class DatiPersonaFisica extends Company {
//constructors
//getters and setters
}
public class DatiDittaIndividuale extends Company {
private String denominazione;
//constructors
//getters and setters
}
Here is a link for the second implementation at OneCompiler 2