Erro de cast em enum

o erro:

Exception in thread "main" java.lang.ClassCastException: class java.lang.Integer cannot be cast to class br.com.alura.jdbc.modelo.Status (java.lang.Integer is in module java.base of loader 'bootstrap'; br.com.alura.jdbc.modelo.Status is in unnamed module of loader 'app')
	at br.com.alura.jdbc.dao.ProdutoDAO.trasformarResultSetEmProduto(ProdutoDAO.java:150)
	at br.com.alura.jdbc.dao.ProdutoDAO.listar(ProdutoDAO.java:66)

o enum:

public enum Status {
	
	EM_ESTOQUE(1), INDISPONIVEL(5), ENCOMENDADO(10);

	private int valor;
	
	Status(int valor) {
		this.valor = valor;
	}
	
	public int getValor() {
		return this.valor;
	}
	
}

a classe produto: No BD o atributo status é integer.

public class Produto {

	private Integer id;
	private String nome;
	private String descricao;
	private Integer categoriaId;
	private String categoriaNome;
	private Status status;

	public Produto(String nome, String descricao) {
		super();
		this.nome = nome;
		this.descricao = descricao;
	}

	public Produto(Integer id, String nome, String descricao, Status status, Integer categoriaId, String categoriaNome)  {

		this.id = id;
		this.nome = nome;
		this.descricao = descricao;
		this.status = status;
		this.categoriaId = categoriaId;
		this.categoriaNome = categoriaNome;
	}

ProdutoDAO:

	public List<Produto> listar() {
		List<Produto> produtos = new ArrayList<Produto>();
		try {
			String sql = "SELECT P.ID, P.NOME, P.DESCRICAO, P.STATUS, C.ID, C.NOME " + "FROM CATEGORIA C "
					+ "INNER JOIN PRODUTO P ON C.ID = P.CATEGORIA_ID";
			
			try (PreparedStatement pstm = connection.prepareStatement(sql)) { //Para garantir o fechamento dos recursos -> a cláusula try-with-resources
				pstm.execute();
	
				trasformarResultSetEmProduto(produtos, pstm);
			}
			return produtos;
		} 
		catch (SQLException e) {
			throw new RuntimeException(e);
		}
	}

	private void trasformarResultSetEmProduto(List<Produto> produtos, PreparedStatement pstm) throws SQLException {
		try (ResultSet rst = pstm.getResultSet()) {
			while (rst.next()) {
				Produto produto = new Produto(rst.getInt(1), rst.getString(2), rst.getString(3), (Status) rst.getObject(4), rst.getInt(5), rst.getString(6));
				produtos.add(produto);
			}
		}
	}

Qualquer dica é bem vinda.

Obrigado.

Cast não funciona porquê o retorno é um inteiro, e o enum não é inteiro, é um objeto com um valor inteiro contido.

Você precisa percorrer os valores do seu enum e comparar a igualdade do atributo valor, e com isso recuperar o tipo enum desejado para setar em seu objeto produto.

1 curtida

Olá Jonathan,

mudei o atributo Status no banco para string e alterei a linha com problema para:

                Produto produto = new Produto(rst.getInt(1), rst.getString(2), rst.getString(3), Status.valueOf(rst.getString(4)), rst.getInt(5), rst.getString(6));

e funcionou.

obrigado pela dica!

abraço! :slight_smile:

1 curtida

@Ricmentz

Apenas para informação. A outra forma (que o @Jonathan_Medeiros mencionou) seria assim:

public enum Status {
	
	EM_ESTOQUE(1), INDISPONIVEL(5), ENCOMENDADO(10);

	private int valor;
	
	Status(int valor) {
		this.valor = valor;
	}
	
	public int getValor() {
		return this.valor;
	}
	
	// Esse método iria recuperar o Status pelo ID cadastrado no banco
	public static Status valueOf(int valor) {
		for (Status status : values()) {
			if (status.valor == valor) {
				return status;
			}
		}

		return null;
	}	
}

E para usar:

int idStatus = 1;
Status status = Status.valueOf(idStatus);
1 curtida

Obrigado pela dica Lucas! Valeu! :+1: