1
resposta

update não funciona, o id permanece nulo

Fiz um projeto semelhante ao da aula, mas agora com a entidade livro, para persistir no banco de dados, mas quando vou fazer o update ele está imprimindo null, mas no banco tem valor... nisso eu não consigo atualizar, sempre cria uma linha nova. Vou colocar o codigo das classes abaixo: classe livro


import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;

@Entity
@Table(name = "livros")
public class Livro {
    
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    private String título;
    private String anoPublicacao;
    private Double preco;
    
    public Livro () {}

    public Livro(String título, String anoPublicacao, Double preco) {
        super();
        this.título = título;
        this.anoPublicacao = anoPublicacao;
        this.preco = preco;
    }

    public Long getId() {
        return id;
    }

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

    public String getTítulo() {
        return título;
    }

    public void setTítulo(String título) {
        this.título = título;
    }

    public String getAnoPublicacao() {
        return anoPublicacao;
    }

    public void setAnoPublicacao(String anoPublicacao) {
        this.anoPublicacao = anoPublicacao;
    }

    public Double getPreco() {
        return preco;
    }

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

classe LivroDao

public void atualizarLivro(Livro livro) {
        EntityManager em = emf.createEntityManager();

        try {
            em.getTransaction().begin();
            
            // Verifica se o livro existe no banco
            Livro livroExistente = em.find(Livro.class, livro.getId());
            
            if (livroExistente != null) {
                // Atualiza o livro usando merge
                em.merge(livro);
            } else {
                System.out.println("Livro com ID " + livro.getId() + " não encontrado.");
            }

            em.getTransaction().commit();
        } catch (Exception e) {
            if (em.getTransaction().isActive()) {
                em.getTransaction().rollback();  // Faz rollback em caso de erro
            }
            e.printStackTrace();
        } finally {
            em.close();  // Fecha o EntityManager
        }
    }

arquivo persistence.xml

<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.2"
    xmlns="http://xmlns.jcp.org/xml/ns/persistence"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence http://xmlns.jcp.org/xml/ns/persistence/persistence_2_2.xsd">

    <persistence-unit name="sistema_gerenciamento_livros" transaction-type="RESOURCE_LOCAL">
        <properties>
             <property name="javax.persistence.jdbc.url" value="jdbc:mysql://localhost:3306/sistema_gerenciamento_livros"/>
            <property name="javax.persistence.jdbc.user" value="root"/>
            <property name="javax.persistence.jdbc.password" value="root"/>
            <property name="javax.persistence.jdbc.driver" value="com.mysql.cj.jdbc.Driver"/>

            <!-- Configurações específicas do Hibernate -->
            <property name="hibernate.dialect" value="org.hibernate.dialect.MySQL8Dialect"/>
            <property name="hibernate.hbm2ddl.auto" value="update"/> <!-- Pode ser "validate", "create", "update", ou "create-drop" -->
            <property name="hibernate.show_sql" value="true"/> <!-- Para mostrar as queries SQL no console -->
            <property name="hibernate.format_sql" value="true"/>
            
        </properties>
    </persistence-unit>
</persistence>

classe de teste

package br.com.sgl.tests;

import javax.persistence.EntityManager;

import br.com.sgl.dao.LivroDao;
import br.com.sgl.model.Livro;
import br.com.sgl.util.JPAUtil;

public class CadastroDeLivros {

    public static void main(String[] args) {
        
        Livro livro1 = new Livro("O senhor dos aneis", "1998", 205.0);

        
        EntityManager em = JPAUtil.getEntityManager();
        LivroDao livroDao = new LivroDao(em);
        
        //criar entidade
        livroDao.cadastrarLivro(livro1);
        livro1.setTítulo("a orfa");
        livro1.setPreco(987.0);
        livro1.setAnoPublicacao("2010");
        livroDao.atualizarLivro(livro1);
        System.out.println(livro1.getId());
        
        //excluir entidade
        //livroDao.excluirLivroPorId(2l);
        
        em.getTransaction().begin();
        
        

        
        

        

        em.getTransaction().commit();
        em.close();

    }

}
1 resposta

Olá Samuel! Tudo bem?

Quando você cria um novo objeto Livro e tenta atualizá-lo sem que ele esteja no estado "managed" pelo EntityManager, o Hibernate não sabe que ele já existe no banco de dados, e por isso, tenta criar uma nova entrada.

Aqui estão algumas dicas que podem ajudar a resolver o problema:

  1. Certifique-se de que o EntityManager está gerenciando a entidade antes de atualizá-la:

    • Quando você cria uma nova instância de Livro e a persiste, ela está no estado "managed". No entanto, se você fechar o EntityManager ou se a transação terminar, a entidade passa para o estado "detached".
    • Para garantir que a entidade está no estado "managed" novamente, você pode usar o método merge() do EntityManager. Isso é importante se você estiver tentando atualizar uma entidade que não foi carregada na mesma sessão do EntityManager.
  2. Verifique o fluxo de transações:

    • Certifique-se de que a transação está sendo corretamente iniciada e finalizada ao redor das operações de persistência e atualização. Isso garante que as mudanças sejam aplicadas ao banco de dados.
  3. Atualize o método de teste:

    • No seu método de teste, após persistir o livro1, você deve garantir que ele ainda está no estado "managed" antes de tentar atualizá-lo. Se você já fechou o EntityManager, você precisará buscar novamente o livro ou usar merge() para que ele volte a ser "managed".

Aqui está um exemplo de como você poderia ajustar o método de teste:

public static void main(String[] args) {
    EntityManager em = JPAUtil.getEntityManager();
    LivroDao livroDao = new LivroDao(em);

    em.getTransaction().begin();
    
    Livro livro1 = new Livro("O senhor dos aneis", "1998", 205.0);
    livroDao.cadastrarLivro(livro1);
    
    // Commit para garantir que o ID seja gerado
    em.getTransaction().commit();
    
    em.getTransaction().begin();
    
    // Agora, livro1 está detached, então precisamos fazer o merge
    livro1 = em.merge(livro1);
    livro1.setTítulo("a orfa");
    livro1.setPreco(987.0);
    livro1.setAnoPublicacao("2010");
    
    em.getTransaction().commit();
    em.close();

    System.out.println(livro1.getId());
}

Espero que essas dicas ajudem a resolver o problema.

Bons estudos!

Caso este post tenha lhe ajudado, por favor, marcar como solucionado ✓.