6
respostas

Erro na hora de listar dados da tabela, não retorna strings

Estou tento um problema em um projeto que estou fazendo. Estou tentando trazer os dados do banco para uma tabela só que não retorna os dados. Vou deixar o código e o erro abaixo, se alguém poder me ajudar só falar aqui.

@Entity
@Table(name = "conteudos")
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn(name = "tipo_conteudo", discriminatorType = DiscriminatorType.STRING)
public abstract class Conteudo {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "conteudo_id")
    private Long id;

    @Column(name = "titulo")
    private String titulo;

    @Column(name = "descricao")
    private String descricao;

    @Column(name = "diretor")
    private String diretor;

    @Column(name = "genero")
    private String genero;

    @Column(name = "data_de_lancamento")
    private LocalDate dataDeLancamento;

    @Column(name = "url_img")
    private String urlImg;

    @Column(name = "url_trailer")
    private String urlTrailer;

    @Column(name = "ativo")
    private Boolean ativo;

    @Column(name = "tipo_conteudo", insertable = false, updatable = false)
    private String tipoConteudo;
    
    @Column(name = "avaliacao_id")
    @OneToMany
    private List<Avaliacoes> listAvaliacoes;

    public Conteudo(String titulo, String descricao, String diretor, String genero, LocalDate dataDeLancamento,
            String urlImg, String urlTrailer) {
        this.titulo = titulo;
        this.descricao = descricao;
        this.diretor = diretor;
        this.genero = genero;
        this.dataDeLancamento = dataDeLancamento;
        this.urlImg = urlImg;
        this.urlTrailer = urlTrailer;
        this.ativo = true;
        this.tipoConteudo = definirTipoConteudo();
    }

    public Conteudo() {}
    
    protected abstract String definirTipoConteudo();
@Entity
@Table(name = "filmes")
@DiscriminatorValue("FILME")
public class Filmes extends Conteudo {

    @Column(name = "duracao")
    private Integer duracao;

    public Filmes(String titulo, String descricao, String diretor, String genero, LocalDate dataDeLancamento,
            String urlImg, String urlTrailer, Integer duracao) {
        super(titulo, descricao, diretor, genero, dataDeLancamento, urlImg, urlTrailer);
        this.duracao = duracao;
    }

    public Filmes() {}
    
    @Override
    protected String definirTipoConteudo() {
        return "Filmes";
    }
public class ConteudoRepository implements IConteudoRepository {

    @Override
    public void cadastrar(Conteudo conteudo) throws SQLException {
        TransacaoUtil.executarTransacao(maneger -> maneger.persist(conteudo));
    }

    @Override
    public Optional<Conteudo> buscarPeloID(long id) throws SQLException {
        return TransacaoUtil.executarTransacaoComRetorno(manager -> {
            return Optional.ofNullable(
                    manager.createQuery("from Conteudo c where c.id = :id and c.ativo = true", Conteudo.class)
                            .setParameter("id", id).getSingleResult());
        });
    }
    
    @Override
    public List<Conteudo> listarConteudos() throws SQLException {
        return TransacaoUtil.executarTransacaoComRetorno(manager -> {
            return manager.createQuery("from Conteudo c where c.ativo = true", Conteudo.class).getResultList();
        });
    }
 
    @Override
    public List<Filmes> listarFilmes() throws SQLException {
        return TransacaoUtil.executarTransacaoComRetorno(manager -> {
            return manager.createQuery("from Filmes f where f.ativo = true", Filmes.class).getResultList();
        });
    }
    
    @Override
    public List<Filmes> listarTop10Filmes() throws SQLException {
        return TransacaoUtil.executarTransacaoComRetorno(maneger -> {
            return maneger.createQuery("SELECT DISTINCT f FROM Filmes f " +
                                        "JOIN f.listAvaliacoes a " +
                                        "GROUP BY f " +
                                        "ORDER BY AVG(a.classificacao) DESC " +
                                        "LIMIT 10 ", Filmes.class).getResultList();
        });
    }
        
    @Override
    public List<Series> listarSeries() throws SQLException {
        return TransacaoUtil.executarTransacaoComRetorno(manager -> {
            return manager.createQuery("from Series s where s.ativo = true", Series.class).getResultList();
        });
    }
    
    @Override
    public List<Series> listarTop10Series() throws SQLException {
        return TransacaoUtil.executarTransacaoComRetorno(maneger -> {
            return maneger.createQuery("SELECT DISTINCT s FROM Series s " +
                                       "JOIN s.listAvaliacoes a " +
                                       "GROUP BY s " +
                                       "ORDER BY AVG(a.classificacao) DESC " +
                                       "LIMIT 10", Series.class).getResultList();
        });
    }

    @Override
    public void alterar(Optional<Conteudo> conteudo) throws SQLException {
        TransacaoUtil.executarTransacao(maneger -> maneger.merge(conteudo));
    }

    @Override
    public void excluirPeloID(Long id) throws SQLException {
        TransacaoUtil.executarTransacao(maneger -> {
            Conteudo conteudo = maneger.find(Conteudo.class, id);
            conteudo.setAtivo(false);
            maneger.merge(conteudo);
        });

    }

}
6 respostas
public class TransacaoUtil {
    public static <T> T executarTransacaoComRetorno(Function<EntityManager, T> function) throws SQLException {
        EntityManager manager = null;
        EntityTransaction transaction = null;

        try {
            manager = JPAUtil.getEntityManager();
            transaction = manager.getTransaction();
            transaction.begin();
            T result = function.apply(manager);
            transaction.commit();
            return result;
        } catch (Exception e) {
            if (transaction != null && transaction.isActive()) {
                transaction.rollback();
            }
            throw new SQLException(e);
        } finally {
            if (manager != null) {
                manager.close();
            }
        }
    }

    public static void executarTransacao(Consumer<EntityManager> consumer) throws SQLException {
        executarTransacaoComRetorno(manager -> {
            consumer.accept(manager);
            return null;
        });
    }
}
public class ConteudoService {
    private ConteudoRepository conteudoRepository;
    
    public ConteudoService() {
        this.conteudoRepository = new ConteudoRepository();
    }
    
    public void cadastrar(Conteudo conteudo) throws SQLException {
        conteudoRepository.cadastrar(conteudo);
    }
    
    public Optional<Conteudo> buscarPeloID(Long id) throws SQLException {
        return conteudoRepository.buscarPeloID(id);
    }
    
    public List<Conteudo> listarConteudo() throws SQLException {
        return conteudoRepository.listarConteudos();
    }
    
    public List<Filmes> listarFilmes() throws SQLException {
        return conteudoRepository.listarFilmes();
    }
    
    public void listarSeries()throws SQLException {
        conteudoRepository.listarSeries();
    }
    
    public void alterar(Optional<Conteudo> conteudo) throws SQLException {
        conteudoRepository.alterar(conteudo);
    }
    
    public void excluir(Long id) throws SQLException {
        conteudoRepository.excluirPeloID(id);
    }
}
public class ListarConteudoBean implements TipoAcao {

    private HttpServletRequest req;
    private HttpServletResponse resp;

    public ListarConteudoBean(HttpServletRequest req, HttpServletResponse resp) {
        this.req = req;
        this.resp = resp;
    }

    @Override
    public void execute() throws ServletException, IOException {

        var service = new ConteudoService();

        List<Conteudo> listConteudo = null;
        try {
            listConteudo = service.listarConteudo();
        } catch (SQLException e) {
            e.printStackTrace();
        }

        this.req.setAttribute("conteudo", listConteudo);

        RequestDispatcher dispatcher = this.req.getRequestDispatcher("/admin.jsp");
        dispatcher.forward(this.req, this.resp);

    }

}
@WebServlet(urlPatterns = "/cine")
public class CineController extends HttpServlet{
private static final long serialVersionUID = 1L;
    
    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        String action = req.getParameter("action");
        
        String fqn = null;
        System.out.println(action);

        if (action != null) {
            fqn = "br.com.cine.model.bean." + Character.toUpperCase(action.charAt(0)) + action.substring(1);
            System.out.println(fqn);
        } else {
            throw new IllegalArgumentException("Nenhuma ação foi informada!");
        }

        try {
            Class<?> classe = Class.forName(fqn);
            Constructor<?> constructor = classe.getDeclaredConstructor(HttpServletRequest.class, HttpServletResponse.class);
            TipoAcao tipoAcao = (TipoAcao) constructor.newInstance(req, resp);
            tipoAcao.execute();
        } catch (ClassNotFoundException | NoSuchMethodException | SecurityException | InstantiationException
                    | IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
            throw new ServletException(e);
        }
    }
}
<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
    pageEncoding="ISO-8859-1"%>
<%@ page import="java.util.List, br.com.cine.model.entities.Conteudo"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix="fmt"%>
<c:url value="/livros?acao=ListarConteudoBean" var="listarConteudo" />
<!DOCTYPE html>
<html>
<head>
<meta charset="ISO-8859-1">
<link rel="stylesheet" href="https://cdn.datatables.net/1.11.5/css/jquery.dataTables.min.css">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/5.3.0/css/bootstrap.min.css">
<link rel="stylesheet" href="https://cdn.datatables.net/1.13.7/css/dataTables.bootstrap5.min.css">
<link rel="stylesheet" href="styles.css">
<title>Insert title here</title>
</head>
<body>
    </header>
    <div class="container">
        <div class="row justify-content-center">
            <div class="col-md-10">
                <h1 class="display-5 mb-4">Listagem</h1>
                <table id="dataTable" class="table table-dark table-striped table-hover">
                    <thead>
                        <tr>
                            <th>Categoria</th>
                            <th>Título</th>
                            <th>Descrição</th>
                            <th>Duração</th>
                            <th>Diretor</th>
                            <th>Data de lançamento</th>
                            <th>Gênero</th>
                            <th>URL da imagem</th>
                            <th>URL do trailer</th>
                            <th>Ações</th>
                        </tr>
                    </thead>
                    <tbody>
                    <c:forEach items="${listarConteudo}" var="conteudo">
                        <tr>
                            <td>${conteudo.tipoConteudo}</td>
                            <td>${conteudo.titulo}</td>
                            <td>${conteudo.descricao}</td>
                            <td>${conteudo.duracao}</td>
                            <td>${conteudo.diretor}</td>
                            <td>${conteudo.urlImg}</td>
                            <td>${conteudo.urlTrailer}</td>
                            <td>
                                <button class="edit">Editar</button>
                                <button class="delete">Excluir</button>
                            </td>
                        </tr>
                    </c:forEach>

                    </tbody>
                </table>
            </div>
        </div>
    </div>

    <script src="https://code.jquery.com/jquery-3.7.0.js"></script>
    <script src="https://cdn.datatables.net/1.13.7/js/jquery.dataTables.min.js"></script>
    <script src="https://cdn.datatables.net/1.13.7/js/dataTables.bootstrap5.min.js"></script>
    <script>
        $(document).ready(function () {
            $('#dataTable').DataTable({
                "theme": "dark",
                "language": {
                  "url": "//cdn.datatables.net/plug-ins/1.11.3/i18n/pt_br.json"
                }
            });
        });
    </script>
</body>
</html>

Insira aqui a descrição dessa imagem para ajudar na acessibilidade

Insira aqui a descrição dessa imagem para ajudar na acessibilidade

A tabela do banco de dados tem esse dado:

Insira aqui a descrição dessa imagem para ajudar na acessibilidade E quando eu pesquiso rodando no java sem ser pelo servidor:

public class Teste {

    public static void main(String[] args) {
        var service = new ConteudoService();
        List<Conteudo> conteudo = null;
        try {
            conteudo = service.listarConteudo();
        } catch (SQLException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        
        System.out.println(conteudo.toString());
    }

}

Retorna isso:

Hibernate: 
    select
        conteudo0_.conteudo_id as conteudo2_1_,
        conteudo0_.ativo as ativo3_1_,
        conteudo0_.data_de_lancamento as data_de_4_1_,
        conteudo0_.descricao as descrica5_1_,
        conteudo0_.diretor as diretor6_1_,
        conteudo0_.genero as genero7_1_,
        conteudo0_.tipo_conteudo as tipo_con1_1_,
        conteudo0_.titulo as titulo8_1_,
        conteudo0_.url_img as url_img9_1_,
        conteudo0_.url_trailer as url_tra10_1_,
        conteudo0_.duracao as duracao11_1_,
        conteudo0_.temporadas as tempora12_1_ 
    from
        conteudos conteudo0_ 
    where
        conteudo0_.ativo=1
[Filmes [duracao=180]]

Eai?

O problema pode estar na forma como você está tentando acessar os atributos específicos de Filmes na sua página JSP. Quando você faz ${conteudo.duracao}, por exemplo, a JSP pode não reconhecer que conteudo é uma instância de Filmes e, portanto, não consegue acessar o atributo duracao.

Uma solução seria verificar o tipo de conteudo antes de tentar acessar atributos específicos. Você pode fazer isso usando a tag <c:choose> e <c:when> na sua JSP. Algo assim:

<c:forEach items="${listarConteudo}" var="conteudo">
    <tr>
        <td>${conteudo.tipoConteudo}</td>
        <td>${conteudo.titulo}</td>
        <td>${conteudo.descricao}</td>
        <c:choose>
            <c:when test="${conteudo instanceof Filmes}">
                <td>${(conteudo as Filmes).duracao}</td>
            </c:when>
            <c:otherwise>
                <td>N/A</td>
            </c:otherwise>
        </c:choose>
        <td>${conteudo.diretor}</td>
        <td>${conteudo.urlImg}</td>
        <td>${conteudo.urlTrailer}</td>
        <td>
            <button class="edit">Editar</button>
            <button class="delete">Excluir</button>
        </td>
    </tr>
</c:forEach>

Isso verifica se conteudo é uma instância de Filmes e, se for, acessa a propriedade duracao. Caso contrário, exibe "N/A" ou o que você preferir.

Valeu!

Tentei aqui continuou o mesmo erro