Ainda não tem acesso? Estude com a gente! Matricule-se
Ainda não tem acesso? Estude com a gente! Matricule-se

Erro ao tentar remover um livro

Boa tarde, a todos!! Ao tentar remover um livro que compõe um venda temos o erro conforme abaixo.

E para não ter o erro estou tentando desabilitar o botão remover para todos os livros que tem relacionamento com alguma venda. Quero que esta ação aconteça no momento em que a tela livro.xhtml seja carregada.

Já criei uma variável booleana no livroBean e a referenciei no disabled do botão remover. Entendo que tenho que criar um método que receba um livro e talvez retorne um boolean para carregar a variável do bean, mas aí fiquei com dúvida quando/como é possível esse método ser acionado no momento em que a tela livro.xhtml seja carregada?

Antecipadamente agradeço a quem puder me orientar na implementação dessa funcionalidade.

Erro ao tentar remover um livro que tenha venda

Caused by: javax.persistence.PersistenceException: org.hibernate.exception.ConstraintViolationException: Cannot delete or update a parent row: a foreign key constraint fails (`livrariadb`.`venda`, CONSTRAINT `FK4EB783CFA17418` FOREIGN KEY (`livro_id`) REFERENCES `livro` (`id`))

Linhas que contém o botão remover no arquivo livro.xhtml

<p:column headerText="Remover">                    
    <p:commandButton update="@form" process="@this" value="remover"  disabled="#{livroBean.habilitaDesabilita}" actionListener="#{livroBean.remover(livro)}" icon="fa fa-fw fa-remove"/>
</p:column>

LivroBean

@Named 
@ViewScoped 
public class LivroBean implements Serializable {

    private static final long serialVersionUID = 1L;

    private Livro livro = new Livro();
    private Integer autorId;
    private List<Livro> livros;
    private LivroDataModel livroDataModel = new LivroDataModel();
    private List<String> generos = Arrays.asList("Romance", "Drama", "Ação");
    private boolean habilitaDesabilita = true;

    @Inject
    private LivroDAO livroDao; 

    @Inject
    private AutorDAO autorDao; 

    @Inject
    private VendaDAO vendaDao; 

    @Inject
    FacesContext context;

    @Transacional
    public void gravar() {
        System.out.println("Gravando livro " + this.livro.getTitulo());

        if (this.livro.getAutores().isEmpty()) {
            context.addMessage("autor", new FacesMessage("Livro deve ter pelo menos um Autor."));
            return;
        } else {

            if (this.livro.getId() == null) {
                livroDao.adiciona(this.livro);
                this.livros = livroDao.listaTodos();
            } else {
                this.livroDao.atualiza(this.livro);
                this.livros = livroDao.listaTodos();
            }

            this.livro = new Livro();

        }
    }

    public void alterar(Livro livro) {

        System.out.println("Carregando livro");
        this.livro = this.livroDao.buscaPorId(livro.getId());    
    }

    @Transacional
    public void remover(Livro livro) {

        System.out.println("Removendo livro");
        this.livroDao.remove(livro);
        this.livros = livroDao.listaTodos();

    }

    public void removerAutorDoLivro(Autor autor) {
        this.livro.removeAutor(autor);
    }

    public String formAutor() {
        System.out.println("Chamando o formulário do Autor");
        return "autor?faces-redirect=true";
    }

    public void comecaComDigitoUm(FacesContext fc, UIComponent component, Object value) throws ValidatorException {
        String valor = value.toString();
        if (!valor.startsWith("1")) {
            throw new ValidatorException(new FacesMessage("ISBN deveria começar com 1"));
        }
    }

    public void gravarAutor() {

        Autor autor = autorDao.buscaPorId(this.autorId);
        this.livro.adicionaAutor(autor);
    }

    public Livro getLivro() {
        return livro;
    }

    @SuppressWarnings({ "unchecked", "rawtypes" })
    public List<Livro> getLivros() {

        if (this.livros == null) {
            this.livros = livroDao.listaTodos();
        }
        return livros;
    }

    @SuppressWarnings({ "unchecked", "rawtypes" })
    public List<Autor> getAutores() {
        return autorDao.listaTodos();
    }

    public List<Autor> getAutoresDoLivro() {
        return this.livro.getAutores();
    }

    public Integer getAutorId() {
        return autorId;
    }

    public void setAutorId(Integer autorId) {
        this.autorId = autorId;
    }

    public LivroDataModel getLivroDataModel() {
        return livroDataModel;
    }

    public List<String> getGeneros() {
        return generos;
    }

    public boolean isHabilitaDesabilita() {
        return habilitaDesabilita;
    }

    public void setHabilitaDesabilita(boolean habilitaDesabilita) {
        this.habilitaDesabilita = habilitaDesabilita;
    }

}
5 respostas

Vicente, boa tarde, esse erro ocorre porque você deve primeiro remover todos os registros de um certo livro na tabela de vendas e depois remover esse livro. Assim, o livro com id = 1 por exemplo só pode ser apagado se não estiver usando esse livro de id = 1 em outras tabelas

Isso mesmo, e por conta disso eu não quero remover o livro que tenha relacionamento com outras tabelas, mas gostaria de desabilitar o botão "remover" para essa situação.

Me perdoem, o que estou querendo deve estar fora do escopo, mas alguém poderia pelo responder se o que estou querendo é possível de ser implementado?

Bom dia Vicente, você pode fazer uma query em vendas, e caso exista uma venda para aquele livro retorno um "true" , e com esse true ou pode habilitar ou desabilitar o botão na tela?

Isso te ajudou? Senão vamos pensar em outra alternativa

Bom dia, Guilherme!

Eu já tenho a query que me devolve um boolean para os livros que tem venda veja abaixo.

Mas como quero que os botões estejam desabilitados no momento em que a tela livro.xhtml for carregada, não sei por exemplo:

  • Por quem ou como esse método será acionado no LivroBean;
  • Como minha variável "boolean habilitaDesabilita" no LivroBean será persistida.

Código do método para retornar boolean para os livro com venda

public boolean buscaVendaPorIdLivro(Livro livro){

        String jpql = "SELECT case when count(v.livro.id) > 0 then true else false end FROM Venda v WHERE v.livro.id = :pLivroId";

        TypedQuery<Boolean> query = em.createQuery(jpql, Boolean.class);

        query.setParameter("pLivroId", livro.getId());

        Boolean resultado = query.getSingleResult();

        return resultado;
    }