I'm new to the world of programming so this could be something very simple that I'm missing. I'm facing a problem when trying to deserialize JSON using Jackson in Java. I have a VendaDTO class with a hierarchy of types (Unico product, Kit product) and I'm getting the error "Could not resolve subtype of [simple type, class com.h2healing.schedule.model.venda.VendaDTO]: missing type id property 'tipo' ". I've already tried configuring Jackson's annotations, but I still haven't been able to solve the problem. Here is the example JSON and relevant code. Any suggestions on how to resolve this?
VendaDTO
package com.h2healing.schedule.model.venda;
import com.fasterxml.jackson.annotation.JsonSubTypes;
import com.fasterxml.jackson.annotation.JsonTypeInfo;
import com.h2healing.schedule.model.cliente.ClienteModel;
import com.h2healing.schedule.model.produto.InterfaceProdutoDTO;
import com.h2healing.schedule.model.produto.ProdutoKitDTO;
import com.h2healing.schedule.model.produto.ProdutoUnicoDTO;
import java.util.List;
@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.PROPERTY, property = "tipo")
@JsonSubTypes({
@JsonSubTypes.Type(value = ProdutoUnicoDTO.class, name = "produtoUnico"),
@JsonSubTypes.Type(value = ProdutoKitDTO.class, name = "produtoKit")
})
public record VendaDTO(
ClienteModel cliente,
List<InterfaceProdutoDTO> produtos,
FormaPagamento formaDePagamento,
String observacao) {
}
ProdutoKitDTO
package com.h2healing.schedule.model.produto;
import com.fasterxml.jackson.annotation.JsonTypeInfo;
import com.fasterxml.jackson.annotation.JsonTypeName;
import java.math.BigDecimal;
import java.util.List;
import java.util.stream.Collectors;
@JsonTypeName("produtoKit")
public record ProdutoKitDTO(
String codigo,
String nomeProduto,
String unidade,
BigDecimal custoUnitario,
BigDecimal valorUnitario,
List<InterfaceProdutoDTO> produtosNoKit) implements InterfaceProdutoDTO {
@Override
public String getTipo() {
return "produtoKit";
}
@Override
public String getCodigo() {
return codigo;
}
@Override
public String getNomeProduto() {
return nomeProduto;
}
@Override
public String getUnidade() {
return unidade;
}
@Override
public BigDecimal getCustoUnitario() {
return custoUnitario;
}
@Override
public BigDecimal getValorUnitario() {
return valorUnitario;
}
@Override
public ProdutoModel toProdutoModel() {
List<Composicao> composicoes = produtosNoKit.stream()
.map(dto -> new Composicao(null, null, (ProdutoUnicoModel) dto.toProdutoModel(), BigDecimal.ZERO))
.collect(Collectors.toList());
ProdutoKitModel produtoKitModel = new ProdutoKitModel();
produtoKitModel.setCodigo(codigo);
produtoKitModel.setNomeProduto(nomeProduto);
produtoKitModel.setUnidade(unidade);
produtoKitModel.setCustoUnitario(custoUnitario);
produtoKitModel.setValorVendaUnitario(valorUnitario);
produtoKitModel.setProdutosNoKit(composicoes);
return produtoKitModel;
}
}
ProdutoUnicoDTO
package com.h2healing.schedule.model.produto;
import com.fasterxml.jackson.annotation.JsonTypeName;
import java.math.BigDecimal;
@JsonTypeName("produtoUnico")
public record ProdutoUnicoDTO(
String codigo,
String nomeProduto,
String unidade,
BigDecimal custoUnitario,
BigDecimal valorUnitario,
BigDecimal saldo
) implements InterfaceProdutoDTO{
@Override
public String getTipo() {
return "produtoUnico";
}
@Override
public String getCodigo() {
return codigo;
}
@Override
public String getNomeProduto() {
return nomeProduto;
}
@Override
public String getUnidade() {
return unidade;
}
@Override
public BigDecimal getCustoUnitario() {
return custoUnitario;
}
@Override
public BigDecimal getValorUnitario() {
return valorUnitario;
}
public BigDecimal getSaldo() {
return saldo;
}
@Override
public ProdutoModel toProdutoModel() {
ProdutoUnicoModel produtoUnicoModel = new ProdutoUnicoModel();
produtoUnicoModel.setCodigo(codigo);
produtoUnicoModel.setNomeProduto(nomeProduto);
produtoUnicoModel.setUnidade(unidade);
produtoUnicoModel.setCustoUnitario(custoUnitario);
produtoUnicoModel.setValorVendaUnitario(valorUnitario);
produtoUnicoModel.setSaldo(saldo);
return produtoUnicoModel;
}
}
InterfaceProdutoDTO
package com.h2healing.schedule.model.produto;
import com.fasterxml.jackson.annotation.JsonTypeInfo;
import java.math.BigDecimal;
public interface InterfaceProdutoDTO {
String getTipo();
String getCodigo();
String getNomeProduto();
String getUnidade();
BigDecimal getCustoUnitario();
BigDecimal getValorUnitario();
ProdutoModel toProdutoModel();
}
JSON
{
"cliente": {
"id": "446f6586-9791-44d4-974f-279654b40da8",
"nome": "Nome do Cliente"
},
"produtos": [
{
"tipo": "produtoUnico",
"codigo": "B01",
"nomeProduto": "Nome do Produto 2",
"unidade": "unidade",
"custoUnitario": 0.0,
"valorUnitario": 0.0,
"saldo": 0.0
},
{
"tipo": "produtoKit",
"codigo": "C03",
"nomeProduto": "Nome do Produto 1",
"unidade": "unidade",
"custoUnitario": 0.0,
"valorUnitario": 0.0,
"produtosNoKit": [
{
"tipo": "produtoUnico",
"codigo": "B02",
"nomeProduto": "Produto no Kit",
"unidade": "unidade",
"custoUnitario": 0.0,
"valorUnitario": 0.0,
"saldo": 0.0
}
]
}
],
"formaDePagamento": "DINHEIRO",
"observacao": "Observação da venda"
}
I faced JSON deserialization issue with Jackson. Initially, I configured the @JsonTypeInfo annotation in the InterfaceProdutoDTO interface and added @JsonTypeName in the concrete classes (ProdutoUnicoDTO and ProdutoKitDTO). However, I still got the exception "Could not resolve subtype of [simple type, class com.h2healing.schedule.model.venda.VendaDTO]: missing type id property 'type'". Then I removed @JsonTypeInfo from the interface and added the getTipo() method to the concrete classes. Despite these changes, the problem persisted. I have reviewed the JSON structure and confirmed that the 'type' property is present. I'm confused about how to resolve this issue and would appreciate any guidance.