Solucionado (ver solução)
Solucionado
(ver solução)
2
respostas

[Bug] NullPointerException

Estou tomando nullpinter exception no metodo listarComProduto() Da classe DAO Categoria DAO, mesmo estando como o do professor... `import java.sql.Connection; import java.sql.SQLException; import java.util.List;

import br.com.alura.jdbc.modelo.Categoria; import br.com.alura.jdbc.modelo.Produto; import dao.CategoriaDAO;

public class TestaListagemDeCategorias {

public static void main(String[] args) throws SQLException {
    try (Connection connection = new ConnectionFactory().recuperarConexao()) {
        CategoriaDAO categoriaDAO = new CategoriaDAO(connection);
        List<Categoria> listaDeCategorias = categoriaDAO.listarComProduto();
        listaDeCategorias.stream().forEach(ct -> {
            System.out.println(ct.getNome());
            for(Produto produto : ct.getProdutos()) {
                System.out.println(ct.getNome() + " - " + produto.getNome());
            }
        });
    }

}

} `

package dao;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

import br.com.alura.jdbc.modelo.Categoria;
import br.com.alura.jdbc.modelo.Produto;

public class CategoriaDAO {

    private Connection connection;

    public CategoriaDAO(Connection connection) {
        this.connection = connection;
    }

    public List<Categoria> listar() throws SQLException {
        List<Categoria> categorias = new ArrayList<>();

        System.out.println("Executando a query de listar categoria");

        String sql = "SELECT ID, NOME FROM CATEGORIA";

        try (PreparedStatement pstm = connection.prepareStatement(sql)) {
            pstm.execute();

            try (ResultSet rst = pstm.getResultSet()) {
                while (rst.next()) {
                    Categoria categoria = new Categoria(rst.getInt(1), rst.getString(2));

                    categorias.add(categoria);
                }
            }
        }
        return categorias;
    }

    public List<Categoria> listarComProduto() throws SQLException{
        Categoria ultima = null;
        List<Categoria> categorias = new ArrayList<>();
        
        String sql = "SELECT C.ID, C.NOME, P.ID, P.NOME, P.DESCRICAO FROM CATEGORIA C INNER JOIN PRODUTO P ON"
                + " C.ID = P.CATEGORIA_ID";
        
        try(PreparedStatement pstm = connection.prepareStatement(sql)){
            pstm.execute();
            
            try(ResultSet rst = pstm.getResultSet()){
                while(rst.next()) {
                    if(ultima == null || !ultima.getNome().equals(rst.getString(2))) {
                        Categoria categoria = new Categoria(rst.getInt(1), rst.getString(2));
                        
                        categorias.add(categoria);
                        ultima = categoria;
                    }
                    Produto produto = new Produto(rst.getInt(3), rst.getString(4), rst.getString(5));
                    ultima.adiciona(produto);
                }
            }
        }
        
        return categorias;

    }
}
package br.com.alura.jdbc.modelo;

import java.util.List;

public class Categoria {
    private int id;
    private String nome;
    private List<Produto> produtos;
    
    public Categoria(int id, String nome){
        this.id = id;
        this.nome = nome;
    }

    public String getNome() {
        return nome;
    }

    public int getId() {
        return id;
    }

    public void adiciona(Produto produto) {
        this.produtos.add(produto);
    }

    public List<Produto> getProdutos() {
        return produtos;
    }
}
Exception in thread "main" java.lang.NullPointerException
    at br.com.alura.jdbc.modelo.Categoria.adiciona(Categoria.java:24)
    at dao.CategoriaDAO.listarComProduto(CategoriaDAO.java:61)
    at TestaListagemDeCategorias.main(TestaListagemDeCategorias.java:14)
2 respostas
solução!

Oi Luis, tudo bem?

Parece que o problema está na classe Categoria. O erro NullPointerException geralmente ocorre quando algo é nulo e você tenta acessá-lo. No seu caso, a lista de produtos na classe Categoria não está sendo inicializada, então quando você tenta adicionar um produto a essa lista no método adiciona(), ocorre o erro.

Para resolver isso vou te dar uma dica, você pode inicializar a lista de produtos no construtor da classe Categoria. Veja como ficaria:

public class Categoria {
    private int id;
    private String nome;
    private List<Produto> produtos;
    
    public Categoria(int id, String nome){
        this.id = id;
        this.nome = nome;
        this.produtos = new ArrayList<>(); // Inicializando a lista de produtos
    }

    public String getNome() {
        return nome;
    }

    public int getId() {
        return id;
    }

    public void adiciona(Produto produto) {
        this.produtos.add(produto);
    }

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

Dessa forma, a lista de produtos será inicializada quando uma nova Categoria for criada, e você poderá adicionar produtos a ela sem problemas.

Um abraço e bons estudos.

Obrigado Lorena, apesar de eu ter encontrado a solução foi interessante a sua resposta para entender melhor :)