[RESOLVIDO] Hibernate - Erro ao alterar campo nome

Os procedimentos comentados funcionaram, menos este de alterar usando o Salvar.

public class Testes {

	public static void main(String[] args)throws Exception {
	
		/*
		RepositorioCliente repositorioCliente = new RepositorioCliente();
		
		Cliente cliente = new Cliente();
		
		// Salvar
		cliente.setNome("Bruce Benner");
		cliente.setIdade(52);
		
		repositorioCliente.salvar(cliente);
		*/
		
		// Listar
//		List<Cliente> clientes = repositorioCliente.listarTodos();
//		
//		for(Cliente temp :clientes) {
//			System.out.println(temp.getNome());
//		}
		
		/*
		// Buscar por id
		RepositorioCliente repositorioCliente = new RepositorioCliente();
		Cliente cliente = repositorioCliente.obterPorId(2);
		System.out.println(cliente.getNome());
		*/
		
		 
		// Atualizar
		
			
		
		RepositorioCliente repositorioCliente = new RepositorioCliente();
		Cliente cliente = repositorioCliente.obterPorId(2);
		cliente.setNome("dom pedro");
		
		repositorioCliente.salvar(cliente);
		
		System.out.println(cliente.getNome()); 
		
	}

}

Deu erro:

INFO: HHH000115: Hibernate connection pool size: 20 (min=1)
Mon Apr 09 18:41:14 BRT 2018 WARN: Establishing SSL connection without server's identity verification is not recommended. According to MySQL 5.5.45+, 5.6.26+ and 5.7.6+ requirements SSL connection must be established by default if explicit option isn't set. For compliance with existing applications not using SSL the verifyServerCertificate property is set to 'false'. You need either to explicitly disable SSL by setting useSSL=false, or set useSSL=true and provide truststore for server certificate verification.
abr 09, 2018 6:41:14 PM org.hibernate.dialect.Dialect <init>
INFO: HHH000400: Using dialect: org.hibernate.dialect.MySQL5Dialect
abr 09, 2018 6:41:14 PM org.hibernate.resource.transaction.backend.jdbc.internal.DdlTransactionIsolatorNonJtaImpl getIsolatedConnection
INFO: HHH10001501: Connection obtained from JdbcConnectionAccess [org.hibernate.engine.jdbc.env.internal.JdbcEnvironmentInitiator$ConnectionProviderJdbcConnectionAccess@6179e425] for (non-JTA) DDL execution was not in auto-commit mode; the Connection 'local transaction' will be committed and the Connection will be set into auto-commit mode.
Hibernate: 
    select
        cliente0_.id as id1_0_0_,
        cliente0_.idade as idade2_0_0_,
        cliente0_.nome as nome3_0_0_ 
    from
        cliente cliente0_ 
    where
        cliente0_.id=?
abr 09, 2018 6:41:14 PM org.hibernate.engine.jdbc.connections.internal.DriverManagerConnectionProviderImpl stop
INFO: HHH10001008: Cleaning up connection pool [jdbc:mysql://localhost/lojaHiber]
 erro ao Salvar:Cannot begin Transaction on closed Session/EntityManager
dom pedro

Cliente.java
@Entity // procura a classe marcada // importar com javax.persistence.Entity;
@Table(name=“cliente”) // Se não especificar copia o nome da classe na tabela
public class Cliente {

// @Id marcando o campo que será a primary key, marcador único
// @GeneratedValue valor que será incrementado no Mysql
@Id
@GeneratedValue(strategy=GenerationType.IDENTITY)
@Column(name="id")
private int id;

@Column(name="nome")  // necessário para dizer a coluna da tabela gerada
private String nome;

@Column(name="idade")
private int idade;



public int getId() {
	return id;
}

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

public String getNome() {
	return nome;
}

public void setNome(String nome) {
	this.nome = nome;
}

public int getIdade() {
	return idade;
}

public void setIdade(int idade) {
	this.idade = idade;
}

}// end class

RepositorioCliente.java

public class RepositorioCliente {
 // Seria uma classe DAO, reponsável por persistir objeto no Baco de Dados
 // CRUD Criar Listar Atualizar Deletar
	
	// EntityManagerFactory Gerencia comunicação com BD
	EntityManagerFactory emf;
	
	// EntityManager faz as transações
	EntityManager em;
	
	public RepositorioCliente() {
		emf = Persistence.createEntityManagerFactory("mottaPU"); // Aqui diz a unidade de persistência especificada no arquivo persistance.xml
		em = emf.createEntityManager();
		
		
	}
	
	//
	public Cliente obterPorId(int id) {
		try {
			em.getTransaction().begin();
			Cliente cliente = em.find(Cliente.class, id);
			em.getTransaction().commit();
			emf.close();
			return cliente;
			
		} catch (Exception e) {
			System.out.println(" erro ao buscar Id :" +e.getMessage());
		}

				
		return null;
		
		
	}
	
	
	public void salvar(Cliente cliente) {
		
			try {
				emf = null;
				// Abrindo conexao com o BD
				em.getTransaction().begin();
				// merge de já existir  cliente ele tenta atualizar, merge pode serusado para atualizar ou criar objeto novo
				em.merge(cliente);  // poderia ser em.persist(cliente);
				// abaixo executa no BD
				em.getTransaction().commit();
				// fechando conexao
				emf.close();
			


			} catch (HibernateException  e) {
				//em.getTransaction().rollback();
				System.out.println(" erro ao Salvar:" +e.getMessage());
			}
		

	}

	public void remover(Cliente cliente) {
    
		try {
			em.getTransaction().begin();
		   // 
			em.remove(cliente);
		   // 
			em.getTransaction().commit();
		  
			emf.close();
			
		} catch (Exception e) {
			em.getTransaction().rollback();
			System.out.println(" erro ao Salvar :" +e.getMessage());
		}
	}
	
	// Listar	
	public List<Cliente> listarTodos(){
		try {
			em.getTransaction().begin();
			// Abaixo importado do jaxa.persistance
			Query consulta = em.createQuery("select cliente from Cliente cliente"); // Não é um SQL puro, é SQL do JPA // consulta JPA
			// abaixo cria uma lista temporaria de clientes		                                                                
			List<Cliente> listaClientes = consulta.getResultList();
			
			em.getTransaction().commit();
			emf.close();
			return listaClientes;
		} catch (Exception e) {
			System.out.println(" erro ao Listar :" +e.getMessage());
		}

				
		return null;
	}
	
	
}// end class

Feito na pasta META-INF em srsc
persistence.xml

<?xml version="1.0" encoding="UTF-8"?>
<persistence version="1.0"
	xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd">
    <persistence-unit name="mottaPU" transaction-type="RESOURCE_LOCAL"> 
        <provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>
    
    <properties>
            
       		<property name="hibernate.archive.autodetection" value="class" />
       		 
        <!-- Conexão com o banco de dados -->
			<property name="hibernate.dialect" value="org.hibernate.dialect.MySQL5Dialect" />
			<property name="hibernate.connection.driver_class" value="com.mysql.jdbc.Driver" />
			<property name="hibernate.connection.url" value="jdbc:mysql://localhost/lojaHiber" />
			<property name="hibernate.connection.user" value="root" />
			<property name="hibernate.connection.password" value="123" />
        <!--<property name="hibernate.hbm2ddl.auto" value="create" /> create cria nova tab/ update atualiza a que já existe-->
            <property name="hibernate.hbm2ddl.auto" value="update"/>
 
        <!--Configuracoes de Debug-->
			<property name="hibernate.show_sql" value="true" />
			<property name="hibernate.format_sql" value="true" />
			<property name="use_sql_comments" value="true" />
		
		</properties>
    </persistence-unit>
</persistence>

Você esta tentando abrir uma transação sendo que a EntityManager esta fechada.

Ps: Não é necessario abrir uma transação para fazer uma busca(find)

1 curtida

provavelmente você deve ter fechado o EntityManeger ou SessionFactore anteriormente, posta sua classe repositorioCliente.

1 curtida

Você não leu o código dele né? Haha a classe esta postada.

Ele fechou a EntityManager no find e depois tentou abrir uma transação

1 curtida

Estou meio confuso, como faço?
Sou novato nisso

Valeu pela dica, agora sim!

RepositorioCliente repositorioCliente = new RepositorioCliente();
		Cliente cliente = repositorioCliente.obterPorId(2);
		cliente.setNome("dom pedro");
		
		RepositorioCliente repositorioCliente2 = new RepositorioCliente();
		repositorioCliente2.salvar(cliente);
		
		System.out.println(cliente.getNome());

Se puderem dar uma força no remover.

	    RepositorioCliente repositorioCliente2 = new RepositorioCliente();
		Cliente cliente = repositorioCliente2.obterPorId(3);
		RepositorioCliente repositorioCliente3 = new RepositorioCliente();
		repositorioCliente3.remover(cliente);

Erro

br 09, 2018 10:38:49 PM org.hibernate.resource.transaction.backend.jdbc.internal.DdlTransactionIsolatorNonJtaImpl getIsolatedConnection
INFO: HHH10001501: Connection obtained from JdbcConnectionAccess [org.hibernate.engine.jdbc.env.internal.JdbcEnvironmentInitiator$ConnectionProviderJdbcConnectionAccess@42e3ede4] for (non-JTA) DDL execution was not in auto-commit mode; the Connection 'local transaction' will be committed and the Connection will be set into auto-commit mode.
Exception in thread "main" java.lang.IllegalArgumentException: Removing a detached instance com.exemplo.entidade.Cliente#3
	at org.hibernate.jpa.event.internal.core.JpaDeleteEventListener.performDetachedEntityDeletionCheck(JpaDeleteEventListener.java:52)
	at org.hibernate.event.internal.DefaultDeleteEventListener.onDelete(DefaultDeleteEventListener.java:89)
	at org.hibernate.event.internal.DefaultDeleteEventListener.onDelete(DefaultDeleteEventListener.java:56)
	at org.hibernate.internal.SessionImpl.fireDelete(SessionImpl.java:993)
	at org.hibernate.internal.SessionImpl.delete(SessionImpl.java:929)
	at org.hibernate.internal.SessionImpl.remove(SessionImpl.java:3357)
	at com.exemplo.repositorio.RepositorioCliente.remover(RepositorioCliente.java:83)
	at com.exemplo.testes.Testes.main(Testes.java:68)

A exceção quer dizer que você esta tentando remover um elemento que não esta no contexto do Hibernate.

Você esta pegando o cliente atraves do repositorioCliente2 e tentando remover pelo repositorioCliente3.

Pesquise sobre CRUD Hibernate, possivelmente te ajudará a dar uns passos.

Da uma olhada nesse link: https://www.devmedia.com.br/jpa-e-hibernate-acessando-dados-em-aplicacoes-java/32711

Repare como é feito a instancia da EntityManager.

CRUD significa: Create, Read, Update e Delete que são as operações basicas de banco de dados caso você não saiba.

1 curtida

tira onde tem essas linhas que deve resolver a questão de conseguir salvar, pesquisar, remover e etc. Você da o close quando está saindo da aplicação, pois no hibernate não compensa toda hora instanciar o EntityManeger.

Ficar toda hora instanciando pode até estar resolvendo seu problema, mas a questão é que faz a aplicação demorar muito mais, mas se for por esse caminho sugiro sempre aproveitar o que você já criou só dando uma nova instancia, ex:

        RepositorioCliente repositorioCliente = new RepositorioCliente();
		Cliente cliente = repositorioCliente.obterPorId(3);
		RepositorioCliente repositorioCliente = new RepositorioCliente();
		repositorioCliente.remover(cliente);
2 curtidas

Sugiro você fazer das duas maneiras que sugeri e então comparar o tempo de execução que você vai ver que apenas remover os emf.close(); vai ser mais rápido.

2 curtidas

Muito obrigado pela ajuda, funcionou!

fiz no RepositorioCliente:
public Cliente obterPorId(int id) {
try {
em.getTransaction().begin();
Cliente cliente = em.find(Cliente.class, id);
em.getTransaction().commit();
//emf.close();
return cliente;

    		} catch (Exception e) {
    			System.out.println(" erro ao buscar Id :" +e.getMessage());
    		}

    				
    		return null;
    		
    		
    	}

Teste.java
RepositorioCliente repositorioCliente = new RepositorioCliente();
Cliente cliente = repositorioCliente.obterPorId(3);
RepositorioCliente repositorioCliente = new RepositorioCliente();
repositorioCliente.remover(cliente);

Como eu disse antes, você não precisa abrir uma transação para fazer um find
Então pode retirar o em.getTransaction().begin() e em.getTransaction().commit() que fica melhor

1 curtida

Se você carrega em uma instância (repositorioCliente2), não conseguirá remover em outra (repositorioCliente3). Delete na mesma.

1 curtida

obrigado

Bixo, nem te conheço e já te amo (sem _iadagem), tava me batendo e tinha um close() atrapalhando minha vida. Valeu parceiro.