Persist nested Java Object using codec

How can I solve the following question about codec:


Maybe you can help me.
Thank you

Hi @Tarcisio_de_Paulo_Rosa_51215,

I have observed this happens when there is some mistake in the query which is written in the code.
I can help better if you can share the exact scenario or code.

Kanika

Hi Kanikasingla
Really the code is just a simulation for understand my problem. Im using Jersey (java), maven, CDI and mongodb to create my actual project.
Below is a simplification of the java classes of the actual project.

@Path("/restaurantes")
@Consumes(MediaType.APPLICATION_JSON + ";charset=utf-8")
@Produces(MediaType.APPLICATION_JSON + ";charset=utf-8")
public class RestauranteResource {

	@Inject
	private RestauranteService service;

    @POST
	public Response inserirRestaurante(Restaurante restaurante) {

		restaurante = this.service.inserirRestaurante(restaurante);

		return Response.status(Status.CREATED).entity(restaurante).build();
	}        
}


public class RestauranteService {

	@Inject
	private RestauranteRepository repository;

    public Restaurante inserirRestaurante(Restaurante restaurante) {
		if (null == restaurante.getId() || "".equals(restaurante.getId())) {
			restaurante.setId(null);
		} else {
			throw new RepositoryException("Novas empresas não podem ser cadastradas já com um identificador",
					Status.BAD_REQUEST);
		}

		return this.repository.inserirRestaurante(restaurante);
	}
}

public class RestauranteRepository {

	@Inject
	private MongoDatabase mongoDatabase;

	private MongoCollection<Restaurante> restauranteCollection;
	private CodecRegistry codecRegistry;
	private final String COLLECTION_RESTAURANTES = "restaurantes";

	public RestauranteRepository() {
		
		RestauranteCodec restauranteCodec = new RestauranteCodec();
		CategoriaCodec categoriaCodec = new CategoriaCodec();
		ProdutoCodec produtoCodec = new ProdutoCodec();

		this.codecRegistry = CodecRegistries.fromRegistries(
				MongoClientSettings.getDefaultCodecRegistry(),
				CodecRegistries.fromCodecs(restauranteCodec, categoriaCodec, produtoCodec)
		);

	}

	@PostConstruct
	public void onInit() {
		this.restauranteCollection = this.mongoDatabase.getCollection(COLLECTION_RESTAURANTES, Restaurante.class)
				.withCodecRegistry(this.codecRegistry);
	}

    public Restaurante inserirRestaurante(Restaurante restaurante) {
		this.restauranteCollection.insertOne(restaurante);
		return restaurante;
	}
}

My Codecs

public class RestauranteCodec implements CollectibleCodec<Restaurante> {

	private final Codec<Document> documentCodec;
	
	public RestauranteCodec() {		
		this.documentCodec = new DocumentCodec();
	}

	public RestauranteCodec(Codec<Document> codec) {		
		this.documentCodec = codec;
	}
	
	@Override
	public void encode(BsonWriter writer, Restaurante restaurante, EncoderContext encoderContext) {
		Document restauranteDoc = new Document();

		String id = restaurante.getId();
		String nome = restaurante.getNome();
		String cnpj = restaurante.getCnpj();
		String nomeResponsavel = restaurante.getNomeResponsavel();
		String urlLogomarca = restaurante.getUrlLogomarca();
		BigDecimal valorEntrega = restaurante.getValorEntrega();
		String slogan = restaurante.getSlogan();
		List<Categoria> categorias = restaurante.getCategorias();

		if (id != null) {
			restauranteDoc.put("_id", new ObjectId(id));
		}
		if (nome != null) {
			restauranteDoc.put("nome", nome);
		}
		if (cnpj != null) {
			restauranteDoc.put("cnpj", cnpj);
		}
		if (nomeResponsavel != null) {
			restauranteDoc.put("nome_responsavel", nomeResponsavel);
		}
		if (urlLogomarca != null) {
			restauranteDoc.put("url_logomarca", urlLogomarca);
		}
		if (valorEntrega != null) {
			restauranteDoc.put("valor_entrega", new Decimal128(valorEntrega));
		}
		if (slogan != null) {
			restauranteDoc.put("slogan", slogan);
		}
		if (categorias != null) {
			restauranteDoc.put("categorias", categorias);
		}
		    		
		this.documentCodec.encode(writer, restauranteDoc, encoderContext);
	}

	@Override
	public Class<Restaurante> getEncoderClass() {		
		return Restaurante.class;
	}

	@Override
	public Restaurante decode(BsonReader reader, DecoderContext decoderContext) {
		Document restaurantDoc = this.documentCodec.decode(reader, decoderContext);
		Restaurante restaurante =  new Restaurante();
		
		restaurante.setId(restaurantDoc.getObjectId("_id").toHexString());
		restaurante.setNome(restaurantDoc.getString("nome"));
		restaurante.setCnpj(restaurantDoc.getString("cnpj"));
		restaurante.setNomeResponsavel(restaurantDoc.getString("nome_responsavel"));
		restaurante.setUrlLogomarca(restaurantDoc.getString("url_logomarca"));
		
		if (restaurantDoc.containsKey("valor_entrega")) { 
				restaurante.setValorEntrega( restaurantDoc.get("valor_entrega", Decimal128.class).bigDecimalValue());
		}
		
		restaurante.setSlogan(restaurantDoc.getString("slogan"));
				
		//Insere as categorias
		List<Document> categoriasDoc =  restaurantDoc.getList("categorias", Document.class);
		List<Categoria> categorias = new CategoriaConverter().convertToListCategoria(categoriasDoc);
		restaurante.setCategorias(categorias);
		
		return restaurante;
	}

	@Override
	public Restaurante generateIdIfAbsentFromDocument(Restaurante restaurante) {
		
		if( !documentHasId(restaurante) ) {
			restaurante.setId(new ObjectId().toHexString());
		}    		
		return restaurante;    		
	}

	@Override
	public boolean documentHasId(Restaurante restaurante) {		
		return null != restaurante.getId();
	}

	@Override
	public BsonValue getDocumentId(Restaurante restaurante) {
		if(!documentHasId(restaurante)) {
			throw new IllegalStateException("Esse documento não tem um _id");
		}
		return new BsonString(restaurante.getId());
	}

}


public class CategoriaCodec implements CollectibleCodec<Categoria>{

	private final Codec<Document> documentCodec;
	
	public CategoriaCodec() {	
		this.documentCodec = new DocumentCodec();
	}
	
	public CategoriaCodec(Codec<Document> codec) {		
		this.documentCodec = codec;
	}
	
	@Override
	public void encode(BsonWriter writer, Categoria value, EncoderContext encoderContext) {    		
		Document categoriaDoc = new Document();
		
		String id = value.getId();
		String descricao = value.getDescricao();
		List<Produto> produtos = value.getProdutos();
			
		if(id != null) {
			categoriaDoc.put("_id", new ObjectId(id));
		}
		if(descricao != null) {
			categoriaDoc.put("descricao", value.getDescricao());
		}
		if(produtos != null) {
			categoriaDoc.put("produtos", produtos);
		}
		
		documentCodec.encode(writer, categoriaDoc, encoderContext);    		
	}

	
	@Override
	public Class<Categoria> getEncoderClass() {		
		return Categoria.class;
	}

	
	
	@Override
	public Categoria decode(BsonReader reader, DecoderContext decoderContext) {    		
		Document document = documentCodec.decode(reader, decoderContext);		
		return new CategoriaConverter().convert(document);
	}

	@Override
	public Categoria generateIdIfAbsentFromDocument(Categoria categoria) {
		if(!this.documentHasId(categoria)) {
			categoria.setId(new ObjectId().toHexString());			
		}
		return categoria;		
	}

	@Override
	public boolean documentHasId(Categoria categoria) {		
		return null != categoria.getId();
	}

	@Override
	public BsonValue getDocumentId(Categoria categoria) {
		if(!documentHasId(categoria)) {
			throw new IllegalStateException("Esse documento não tem um _id");
		}    		
		return new BsonString(categoria.getId());    		
	}
	
}


public class ProdutoCodec implements CollectibleCodec<Produto>{
	
	private final Codec<Document> documentCodec;
	
	public ProdutoCodec() {
		this.documentCodec = new DocumentCodec();
	}
	
	public ProdutoCodec(Codec<Document> codec) {
		this.documentCodec = codec;
	}

	@Override
	public void encode(BsonWriter writer, Produto produto, EncoderContext encoderContext) {
		Document produtoDoc = new Document();
		
		String id = produto.getId();
		String descricao = produto.getDescricao();
		String linkImage = produto.getLinkImage();
		
		if(id != null) {
			produtoDoc.put("_id", new ObjectId(id));			
		}
		if(descricao != null) {
			produtoDoc.put("descricao", produto.getDescricao());
		}
		if(linkImage != null) {
			produtoDoc.put("linkImage", produto.getLinkImage());
		}
		
		this.documentCodec.encode(writer, produtoDoc, encoderContext);
		
	}

	@Override
	public Class<Produto> getEncoderClass() {	
		return Produto.class;
	}

	@Override
	public Produto decode(BsonReader reader, DecoderContext decoderContext) {
		Document produtoDoc = this.documentCodec.decode(reader, decoderContext);		
		
		return new ProdutoConverter().convert(produtoDoc);
	}

	@Override
	public Produto generateIdIfAbsentFromDocument(Produto produto) {
		if(!this.documentHasId(produto)) {
			produto.setId(new ObjectId().toHexString());
		}
		return produto;
	}

	@Override
	public boolean documentHasId(Produto produto) {		
		return null != produto.getId();
	}

	@Override
	public BsonValue getDocumentId(Produto produto) {
		if(!this.documentHasId(produto)) {
			throw new IllegalStateException("Esse documento não tem um _id");
		}
		return new BsonString(produto.getId());
	}

}

I haven’t created the other codecs yet.

My Converters

public class CategoriaConverter {

	public CategoriaConverter() {
		
	}    	
	
	public Categoria convert(Document doc) {    		
		Categoria categoria = new Categoria();
		
		if(doc.getObjectId("_id") != null) {
			categoria.setId(doc.getObjectId("_id").toHexString());
		}
		
		categoria.setDescricao(doc.getString("descricao"));    		
		return categoria;
	}    	
	
	public Document convert(Categoria categoria) {
		Document doc = new Document();
		if(categoria.getId() != null) {
			doc.put("_id", new ObjectId(categoria.getId()));
		}
		doc.put("descricao", categoria.getDescricao());
		return doc;
	}
	
	public List<Document> convertToListDocument(List<Categoria> categorias){
		List<Document> docs = new ArrayList<Document>();
		if(categorias == null) {
			return Collections.emptyList();
		}
		for(Categoria cat : categorias) {
			docs.add( this.convert(cat) );
		}
		return docs;
	}
	
	public List<Categoria> convertToListCategoria(List<Document> categoriaDocs){		
		List<Categoria> categorias = new ArrayList<Categoria>();	
		if(categoriaDocs == null) {
			return Collections.emptyList();
		}
		for(Document doc: categoriaDocs) {			
			categorias.add( this.convert(doc) );
		}
		return categorias;
	}
}


public class ProdutoConverter {

	public ProdutoConverter() {
	
	}
	
	public Document convert(Produto produto) {
		Document doc = new Document();
		doc.put("_id", produto.getId());
		doc.put("descricao", produto.getDescricao());
		//doc.put("preco", produto.getDescricao());
		doc.put("linkImage", produto.getDescricao());
		
		return doc;
	}
	
	public Produto convert(Document doc) {
		Produto produto = new Produto();
		produto.setId(doc.getObjectId("_id").toHexString());
		produto.setDescricao(doc.getString("descricao"));
		//produto.setPreco(doc.getString("preco"));
		produto.setLinkImage(doc.getString("linkImage"));
	
		return produto;
	}
}

My model class

public class Restaurante {
	
	private String id;    	
	private String nome;
	private String cnpj;
	private String nomeResponsavel;
	private String urlLogomarca;
	private BigDecimal valorEntrega;
	private String slogan;
	
	private List<Categoria> categorias;	
	private Set<Visibility> visibilidade;		
	private Endereco endereco;
	    	
	/* Construtor */
	public Restaurante() {
		this.valorEntrega = new BigDecimal(0);
		this.categorias = new ArrayList<Categoria>();
	}
	
	/* Setters e Getters */
	public String getId() {
		return id;
	}

	public void setId(String id) {
		this.id = id;
	}

	public String getNome() {
		return nome;
	}

	public void setNome(String nome) {
		this.nome = nome;
	}

	public String getCnpj() {
		return cnpj;
	}

	public void setCnpj(String cnpj) {
		this.cnpj = cnpj;
	}

	public String getNomeResponsavel() {
		return nomeResponsavel;
	}

	public void setNomeResponsavel(String nomeResponsavel) {
		this.nomeResponsavel = nomeResponsavel;
	}

	public Set<Visibility> getVisibilidade() {
		return visibilidade;
	}

	public void setVisibilidade(Set<Visibility> visibilidade) {
		this.visibilidade = visibilidade;
	}

	public Endereco getEndereco() {
		return endereco;
	}

	public void setEndereco(Endereco endereco) {
		this.endereco = endereco;
	}

	public List<Categoria> getCategorias() {
		return categorias;
	}

	public void setCategorias(List<Categoria> categorias) {
		this.categorias = categorias;
	}
	
	public String getUrlLogomarca() {
		return urlLogomarca;
	}

	public void setUrlLogomarca(String urlLogomarca) {
		this.urlLogomarca = urlLogomarca;
	}
	
	public BigDecimal getValorEntrega() {
		return valorEntrega;
	}

	public void setValorEntrega(BigDecimal valorEntrega) {
		this.valorEntrega = valorEntrega;
	}
	
	public String getSlogan() {
		return slogan;
	}

	public void setSlogan(String slogan) {
		this.slogan = slogan;
	}

	public Categoria findCategoria(String idCategoria) {
		for(Categoria categoria : this.categorias) {
			if(categoria.getId() == idCategoria) {
				return categoria;
			}
		}
		return null;
	}
		
	
	/* hasCode e Equals */	
	
	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime * result + ((id == null) ? 0 : id.hashCode());
		return result;
	}

	@Override
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (getClass() != obj.getClass())
			return false;
		Restaurante other = (Restaurante) obj;
		if (id == null) {
			if (other.id != null)
				return false;
		} else if (!id.equals(other.id))
			return false;
		return true;
	}

    @Override
	public String toString() {
		return "Restaurante [id=" + id + ", nome=" + nome + ", cnpj=" + cnpj + ", nomeResponsavel=" + nomeResponsavel
				+ ", urlLogomarca=" + urlLogomarca + ", valorEntrega=" + valorEntrega + ", slogan=" + slogan
				+ ", categorias=" + categorias + ", visibilidade=" + visibilidade + ", endereco=" + endereco + "]";
    	}
}


public class Categoria {
	
	private String id;	
	private String descricao;		
	private List<Produto> produtos;
		    	
	/* Construtor */
	public Categoria() {
		
	}
	
	/* Setters e getters */
	
	public String getId() {
		return id;
	}

	public void setId(String id) {
		this.id = id;
	}

	public String getDescricao() {
		return descricao;
	}

	public void setDescricao(String descricao) {
		this.descricao = descricao;
	}

	public List<Produto> getProdutos() {
		return produtos;
	}

	public void setProdutos(List<Produto> produtos) {
		this.produtos = produtos;
	}
	
	
	public void addProduto(Produto produto) {
		this.produtos.add(produto);		
	}
	
	public void removeProduto(Produto produto) {
		this.produtos.remove(produto);		
	}
	
	public Produto findProduto(String idProduto) {		
		for(Produto produto : this.produtos) {
			if(produto.getId() == idProduto) {
				return produto;
			}
		}
		return null;
	}
	

	/* hascode e equals */	

	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime * result + ((id == null) ? 0 : id.hashCode());
		return result;
	}

	@Override
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (getClass() != obj.getClass())
			return false;
		Categoria other = (Categoria) obj;
		if (id == null) {
			if (other.id != null)
				return false;
		} else if (!id.equals(other.id))
			return false;
		return true;
	}

	@Override
	public String toString() {
		return "Categoria [id=" + id + ", descricao=" + descricao + ", produtos=" + produtos + "]";
	}

}


public class Produto {

	private String id;	
	private String descricao;
	private String preco;
	private String linkImage;
	
	private List<Ingrediente> ingredientes;	
	private List<Adicional> adicionais;	
	private List<Acompanhamento> acompanhamentos;
	private List<Tamanho> opcoesDeTamanho;
	private List<MultiEscolha> multiEscolha;
	
	/* Construtor */
	public Produto() {

	}

	public String getId() {
		return id;
	}

	public void setId(String id) {
		this.id = id;
	}

	public String getDescricao() {
		return descricao;
	}

	public void setDescricao(String descricao) {
		this.descricao = descricao;
	}

	public String getPreco() {
		return preco;
	}

	public void setPreco(String preco) {
		this.preco = preco;
	}

	public String getLinkImage() {
		return linkImage;
	}

	public void setLinkImage(String linkImage) {
		this.linkImage = linkImage;
	}
	
	public List<Ingrediente> getIngredientes() {
		return ingredientes;
	}

	public void setIngredientes(List<Ingrediente> ingredientes) {
		this.ingredientes = ingredientes;
	}

	public List<Adicional> getAdicionais() {
		return adicionais;
	}

	public void setAdicionais(List<Adicional> adicionais) {
		this.adicionais = adicionais;
	}

	public List<Acompanhamento> getAcompanhamentos() {
		return acompanhamentos;
	}

	public void setAcompanhamentos(List<Acompanhamento> acompanhamentos) {
		this.acompanhamentos = acompanhamentos;
	}

	public List<Tamanho> getOpcoesDeTamanho() {
		return opcoesDeTamanho;
	}

	public void setOpcoesDeTamanho(List<Tamanho> opcoesDeTamanho) {
		this.opcoesDeTamanho = opcoesDeTamanho;
	}

	public List<MultiEscolha> getMultiEscolha() {
		return multiEscolha;
	}

	public void setMultiEscolha(List<MultiEscolha> multiEscolha) {
		this.multiEscolha = multiEscolha;
	}
	
	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime * result + ((id == null) ? 0 : id.hashCode());
		return result;
	}

	@Override
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (getClass() != obj.getClass())
			return false;
		Produto other = (Produto) obj;
		if (id == null) {
			if (other.id != null)
				return false;
		} else if (!id.equals(other.id))
			return false;
		return true;
	}
	
}

The error that occurs

GRAVE: Servlet.service() for servlet [Jersey Web Application] in context with path [/wsgula7] threw exception [org.bson.codecs.configuration.CodecConfigurationException: Can't find a codec for class br.com.gula7.ws.models.Categoria.] with root cause
org.bson.codecs.configuration.CodecConfigurationException: Can't find a codec for class br.com.gula7.ws.models.Categoria.
	at org.bson.codecs.configuration.CodecCache.getOrThrow(CodecCache.java:46)
	at org.bson.codecs.configuration.ProvidersCodecRegistry.get(ProvidersCodecRegistry.java:63)
	at org.bson.codecs.configuration.ProvidersCodecRegistry.get(ProvidersCodecRegistry.java:37)
	at org.bson.codecs.DocumentCodec.writeValue(DocumentCodec.java:184)
	at org.bson.codecs.DocumentCodec.writeIterable(DocumentCodec.java:207)
	at org.bson.codecs.DocumentCodec.writeValue(DocumentCodec.java:180)
	at org.bson.codecs.DocumentCodec.writeMap(DocumentCodec.java:199)
	at org.bson.codecs.DocumentCodec.encode(DocumentCodec.java:141)
	at org.bson.codecs.DocumentCodec.encode(DocumentCodec.java:45)
	at br.com.gula7.ws.util.mongodbCodecs.RestauranteCodec.encode(RestauranteCodec.java:75)
	at br.com.gula7.ws.util.mongodbCodecs.RestauranteCodec.encode(RestauranteCodec.java:1)
	at org.bson.codecs.BsonDocumentWrapperCodec.encode(BsonDocumentWrapperCodec.java:63)
	at org.bson.codecs.BsonDocumentWrapperCodec.encode(BsonDocumentWrapperCodec.java:29)
	at com.mongodb.operation.BulkWriteBatch$WriteRequestEncoder.encode(BulkWriteBatch.java:385)
	at com.mongodb.operation.BulkWriteBatch$WriteRequestEncoder.encode(BulkWriteBatch.java:375)
	at org.bson.codecs.BsonDocumentWrapperCodec.encode(BsonDocumentWrapperCodec.java:63)
	at org.bson.codecs.BsonDocumentWrapperCodec.encode(BsonDocumentWrapperCodec.java:29)
	at com.mongodb.internal.connection.BsonWriterHelper.writeDocument(BsonWriterHelper.java:75)
	at com.mongodb.internal.connection.BsonWriterHelper.writePayload(BsonWriterHelper.java:59)
	at com.mongodb.internal.connection.CommandMessage.encodeMessageBodyWithMetadata(CommandMessage.java:147)
	at com.mongodb.internal.connection.RequestMessage.encode(RequestMessage.java:138)
	at com.mongodb.internal.connection.CommandMessage.encode(CommandMessage.java:61)
	at com.mongodb.internal.connection.InternalStreamConnection.sendAndReceive(InternalStreamConnection.java:248)
	at com.mongodb.internal.connection.UsageTrackingInternalConnection.sendAndReceive(UsageTrackingInternalConnection.java:99)
	at com.mongodb.internal.connection.DefaultConnectionPool$PooledConnection.sendAndReceive(DefaultConnectionPool.java:450)
	at com.mongodb.internal.connection.CommandProtocolImpl.execute(CommandProtocolImpl.java:72)
	at com.mongodb.internal.connection.DefaultServer$DefaultServerProtocolExecutor.execute(DefaultServer.java:218)
	at com.mongodb.internal.connection.DefaultServerConnection.executeProtocol(DefaultServerConnection.java:269)
	at com.mongodb.internal.connection.DefaultServerConnection.command(DefaultServerConnection.java:131)
	at com.mongodb.operation.MixedBulkWriteOperation.executeCommand(MixedBulkWriteOperation.java:434)
	at com.mongodb.operation.MixedBulkWriteOperation.executeBulkWriteBatch(MixedBulkWriteOperation.java:260)
	at com.mongodb.operation.MixedBulkWriteOperation.access$700(MixedBulkWriteOperation.java:71)
	at com.mongodb.operation.MixedBulkWriteOperation$1.call(MixedBulkWriteOperation.java:204)
	at com.mongodb.operation.MixedBulkWriteOperation$1.call(MixedBulkWriteOperation.java:195)
	at com.mongodb.operation.OperationHelper.withReleasableConnection(OperationHelper.java:501)
	at com.mongodb.operation.MixedBulkWriteOperation.execute(MixedBulkWriteOperation.java:195)
	at com.mongodb.operation.MixedBulkWriteOperation.execute(MixedBulkWriteOperation.java:70)
	at com.mongodb.client.internal.MongoClientDelegate$DelegateOperationExecutor.execute(MongoClientDelegate.java:206)
	at com.mongodb.client.internal.MongoCollectionImpl.executeSingleWriteRequest(MongoCollectionImpl.java:1048)
	at com.mongodb.client.internal.MongoCollectionImpl.executeInsertOne(MongoCollectionImpl.java:498)
	at com.mongodb.client.internal.MongoCollectionImpl.insertOne(MongoCollectionImpl.java:482)
	at com.mongodb.client.internal.MongoCollectionImpl.insertOne(MongoCollectionImpl.java:476)
	at br.com.gula7.ws.repository.RestauranteRepository.inserirRestaurante(RestauranteRepository.java:69)
	at br.com.gula7.ws.service.RestauranteService.inserirRestaurante(RestauranteService.java:44)
	at br.com.gula7.ws.resources.RestauranteResource.inserirRestaurante(RestauranteResource.java:94)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:498)
	at org.glassfish.jersey.server.model.internal.ResourceMethodInvocationHandlerFactory.lambda$static$0(ResourceMethodInvocationHandlerFactory.java:52)
	at org.glassfish.jersey.server.model.internal.AbstractJavaResourceMethodDispatcher$1.run(AbstractJavaResourceMethodDispatcher.java:124)
	at org.glassfish.jersey.server.model.internal.AbstractJavaResourceMethodDispatcher.invoke(AbstractJavaResourceMethodDispatcher.java:167)
	at org.glassfish.jersey.server.model.internal.JavaResourceMethodDispatcherProvider$ResponseOutInvoker.doDispatch(JavaResourceMethodDispatcherProvider.java:176)
	at org.glassfish.jersey.server.model.internal.AbstractJavaResourceMethodDispatcher.dispatch(AbstractJavaResourceMethodDispatcher.java:79)
	at org.glassfish.jersey.server.model.ResourceMethodInvoker.invoke(ResourceMethodInvoker.java:469)
	at org.glassfish.jersey.server.model.ResourceMethodInvoker.apply(ResourceMethodInvoker.java:391)
	at org.glassfish.jersey.server.model.ResourceMethodInvoker.apply(ResourceMethodInvoker.java:80)
	at org.glassfish.jersey.server.ServerRuntime$1.run(ServerRuntime.java:253)
	at org.glassfish.jersey.internal.Errors$1.call(Errors.java:248)
	at org.glassfish.jersey.internal.Errors$1.call(Errors.java:244)
	at org.glassfish.jersey.internal.Errors.process(Errors.java:292)
	at org.glassfish.jersey.internal.Errors.process(Errors.java:274)
	at org.glassfish.jersey.internal.Errors.process(Errors.java:244)
	at org.glassfish.jersey.process.internal.RequestScope.runInScope(RequestScope.java:265)
	at org.glassfish.jersey.server.ServerRuntime.process(ServerRuntime.java:232)
	at org.glassfish.jersey.server.ApplicationHandler.handle(ApplicationHandler.java:679)
	at org.glassfish.jersey.servlet.WebComponent.serviceImpl(WebComponent.java:392)
	at org.glassfish.jersey.servlet.WebComponent.service(WebComponent.java:346)
	at org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:365)
	at org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:318)
	at org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:205)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:231)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
	at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
	at org.apache.catalina.filters.CorsFilter.handleNonCORS(CorsFilter.java:352)
	at org.apache.catalina.filters.CorsFilter.doFilter(CorsFilter.java:171)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
	at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:200)
	at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:96)
	at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:490)
	at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:139)
	at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92)
	at org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:668)
	at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:74)
	at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:343)
	at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:408)
	at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:66)
	at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:834)
	at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1415)
	at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)
	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
	at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
	at java.lang.Thread.run(Thread.java:748)

If you need the other classes (pojo) such as:ingredientes, adicionais, acompanhamentos, opcoesDeTamanho e multiEscolha let me know.

I have no knowledge of Jersey Web Application. But this error will make me look at my Codec class for Categoria. I see that you have created this already.

Maybe try checking the order of Codec files. As it can be possible that loop is not closed or some syntax issue. I will research on this and will get back to you.

Kanika

I checked the code and didn’t find the error. I am already believing it must be a java driver problem. Is it possible to use codecs internally in another codec?

I reproduced this scenario (master/detail) and really the problem is in Mongodb Java Driver. If I execute insertOne without inserting detail, the execution is successful, but the codec throws the error “CodecConfigurationException” whenever I insert some detail. This is a bug because the driver is unable to trigger cascading codecs.

Hi @Tarcisio_de_Paulo_Rosa_51215,

Thanks for doing this great research. I will notify the team and will get back to you. :slight_smile:

Kanika

Hi Kanika
I received a response on stack overflow: https://stackoverflow.com/a/57746382/4621678

The IDs in the POJO are string type and I would like to handle this in the codec (as I watched in the mogodb for java developers training video). I would also like to set Ids in the codec for a new objectId when they are null or empty.
Thanks for your help.