Jpa - update utilizando merge

13 respostas
jpa
Cleiton_Conceicao

gente não sei se é a forma mais rápida e fácil de fazer. porém o problema é o seguinte
estou tentando realizar um update ,porém o método está inserindo no banco.
vou deixar o código abaixo para vocês observarem o que estou fazendo de errado

public void alterardados(Usuario ServletAlterarUsuario){

EntityManagerFactory emf = Persistence.createEntityManagerFactory("teste");
EntityManager em = emf.createEntityManager();
Usuario CADASTRO_USUARIO = new Usuario();


CADASTRO_USUARIO.setUSR_NOME(ServletAlterarUsuario.getUSR_NOME());
CADASTRO_USUARIO.setUSR_CPF(ServletAlterarUsuario.getUSR_CPF());
CADASTRO_USUARIO.setUSR_EMAIL(ServletAlterarUsuario.getUSR_EMAIL());
CADASTRO_USUARIO.setUSR_SENHA(ServletAlterarUsuario.getUSR_SENHA());
CADASTRO_USUARIO.setUSR_TELEFONE(ServletAlterarUsuario.getUSR_TELEFONE());
CADASTRO_USUARIO.setUSR_CELULAR(ServletAlterarUsuario.getUSR_CELULAR());
CADASTRO_USUARIO.setUSR_CEP(ServletAlterarUsuario.getUSR_CEP());
CADASTRO_USUARIO.setUSR_NUMERO(ServletAlterarUsuario.getUSR_NUMERO());
CADASTRO_USUARIO.setUSR_LOGRADOURO(ServletAlterarUsuario.getUSR_LOGRADOURO());
CADASTRO_USUARIO.setUSR_BAIRRO(ServletAlterarUsuario.getUSR_BAIRRO());
CADASTRO_USUARIO.setUSR_LOCALIDADE(ServletAlterarUsuario.getUSR_LOCALIDADE());
CADASTRO_USUARIO.setUSR_ESTADO(ServletAlterarUsuario.getUSR_ESTADO());
em.getTransaction().begin();
em.merge(CADASTRO_USUARIO);
em.getTransaction().commit();

em.close();

System.out.println("usuário alterado com sucesso!!");

}

13 Respostas

javaflex

Posta o SQL gerado por essa ferramenta.

Cleiton_Conceicao

ele n gerou sql nenhum,

nov 29, 2017 6:55:35 PM org.hibernate.engine.jdbc.connections.internal.DriverManagerConnectionProviderImpl configure

WARN: HHH10001002: Using Hibernate built-in connection pool (not for production use!)

nov 29, 2017 6:55:35 PM org.hibernate.engine.jdbc.connections.internal.DriverManagerConnectionProviderImpl buildCreator

INFO: HHH10001005: using driver [com.mysql.jdbc.Driver] at URL [jdbc:mysql://localhost:3306/sistema_escolar]

nov 29, 2017 6:55:35 PM org.hibernate.engine.jdbc.connections.internal.DriverManagerConnectionProviderImpl buildCreator

INFO: HHH10001001: Connection properties: {user=root, password=<strong><strong>}

nov 29, 2017 6:55:35 PM org.hibernate.engine.jdbc.connections.internal.DriverManagerConnectionProviderImpl buildCreator

INFO: HHH10001003: Autocommit mode: false

nov 29, 2017 6:55:35 PM org.hibernate.engine.jdbc.connections.internal.PooledConnections 

INFO: HHH000115: Hibernate connection pool size: 20 (min=1)

nov 29, 2017 6:55:35 PM org.hibernate.dialect.Dialect 

INFO: HHH000400: Using dialect: org.hibernate.dialect.MySQLDialect

nov 29, 2017 6:55:35 PM org.hibernate.resource.transaction.backend.jdbc.internal.DdlTransactionIsolatorNonJtaImpl getIsolatedConnection

INFO: HHH10001501: Connection obtained from JdbcConnectionAccess [org.hibernate.engine.jdbc.env.internal.JdbcEnvironmentInitiator$ConnectionProviderJdbcConnectionAccess@4698e935] 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.

usuário alterado com sucesso!!

nov 29, 2017 6:55:38 PM org.hibernate.jpa.internal.util.LogHelper logPersistenceUnitInformation

INFO: HHH000204: Processing PersistenceUnitInfo [

name: teste

]

nov 29, 2017 6:55:38 PM org.hibernate.engine.jdbc.connections.internal.DriverManagerConnectionProviderImpl configure

WARN: HHH10001002: Using Hibernate built-in connection pool (not for production use!)

nov 29, 2017 6:55:38 PM org.hibernate.engine.jdbc.connections.internal.DriverManagerConnectionProviderImpl buildCreator

INFO: HHH10001005: using driver [com.mysql.jdbc.Driver] at URL [jdbc:mysql://localhost:3306/sistema_escolar]

nov 29, 2017 6:55:38 PM org.hibernate.engine.jdbc.connections.internal.DriverManagerConnectionProviderImpl buildCreator

INFO: HHH10001001: Connection properties: {user=root, password=</strong></strong>}

nov 29, 2017 6:55:38 PM org.hibernate.engine.jdbc.connections.internal.DriverManagerConnectionProviderImpl buildCreator

INFO: HHH10001003: Autocommit mode: false

nov 29, 2017 6:55:38 PM org.hibernate.engine.jdbc.connections.internal.PooledConnections 

INFO: HHH000115: Hibernate connection pool size: 20 (min=1)

nov 29, 2017 6:55:38 PM org.hibernate.dialect.Dialect 

INFO: HHH000400: Using dialect: org.hibernate.dialect.MySQLDialect

nov 29, 2017 6:55:38 PM org.hibernate.resource.transaction.backend.jdbc.internal.DdlTransactionIsolatorNonJtaImpl getIsolatedConnection

INFO: HHH10001501: Connection obtained from JdbcConnectionAccess [org.hibernate.engine.jdbc.env.internal.JdbcEnvironmentInitiator$ConnectionProviderJdbcConnectionAccess@73e79996] 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.

nov 29, 2017 6:55:39 PM org.hibernate.hql.internal.QueryTranslatorFactoryInitiator initiateService

INFO: HHH000397: Using ASTQueryTranslatorFactory
javaflex

Se ele inseriu gerou INSERT, nao tem mágica.

Se quer fazer update dessa forma com JPA/Hibernate terá que carregar o objeto do banco antes e não criar um objeto do zero (new).

C

você poderia fazer um exemplo para poder eu entender melhor?

staroski

em.persist(ServletAlterarUsuario);

Simples assim.

C

não estou em casa agora.
mas no caso eu teria que trocar o

Usuario CADASTRO_USUARIO = new Usuario();
por

em.persist(ServletAlterarUsuario);

?

me desculpa a burrice. é pq ainda tenho 2 telas pra fazer e o trabalho é pra entregar sexta.

Cleiton_Conceicao

eu achei q não entendi direito. fiz essas mudanças e não deu certo.

javaflex

Tem várias formas. A forma mais sob controle:

em.getTransaction().begin();
Usuario CADASTRO_USUARIO = em.find(Usuario.class, ServletAlterarUsuario.getID());
//altera somente os campos que vieram da tela em questao
CADASTRO_USUARIO.setUSR_NOME(ServletAlterarUsuario.getUSR_NOME());
CADASTRO_USUARIO.setUSR_CPF(ServletAlterarUsuario.getUSR_CPF());
//etc..
em.getTransaction().commit();

Se quiser usar merge dá uma estudada antes pois pode ser perigoso se nao souber o que está fazendo. Exemplo: https://www.treinaweb.com.br/blog/entendendo-o-metodo-merge-do-jpa/

staroski

Se você quer fazer atualizar um registro na base, não faz sentido instanciar outro objeto setando as mesmas propriedades.
Você já recebe o Usuario alterado por parâmetro, é só fazer o persist dele.

Cleiton_Conceicao

eu fiz isso.

public void alterardados(Usuario ServletAlterarUsuario){

EntityManagerFactory emf = Persistence.createEntityManagerFactory(teste);

EntityManager em = emf.createEntityManager();

em.getTransaction().begin();

Usuario CADASTRO_USUARIO = em.find(Usuario.class, ServletAlterarUsuario.getUSR_CODIGO());	

CADASTRO_USUARIO.setUSR_NOME(ServletAlterarUsuario.getUSR_NOME());

CADASTRO_USUARIO.setUSR_CPF(ServletAlterarUsuario.getUSR_CPF());

CADASTRO_USUARIO.setUSR_EMAIL(ServletAlterarUsuario.getUSR_EMAIL());

CADASTRO_USUARIO.setUSR_SENHA(ServletAlterarUsuario.getUSR_SENHA());

CADASTRO_USUARIO.setUSR_TELEFONE(ServletAlterarUsuario.getUSR_TELEFONE());

CADASTRO_USUARIO.setUSR_CELULAR(ServletAlterarUsuario.getUSR_CELULAR());

CADASTRO_USUARIO.setUSR_CEP(ServletAlterarUsuario.getUSR_CEP());

CADASTRO_USUARIO.setUSR_NUMERO(ServletAlterarUsuario.getUSR_NUMERO());

CADASTRO_USUARIO.setUSR_LOGRADOURO(ServletAlterarUsuario.getUSR_LOGRADOURO());

CADASTRO_USUARIO.setUSR_BAIRRO(ServletAlterarUsuario.getUSR_BAIRRO());

CADASTRO_USUARIO.setUSR_LOCALIDADE(ServletAlterarUsuario.getUSR_LOCALIDADE());

CADASTRO_USUARIO.setUSR_ESTADO(ServletAlterarUsuario.getUSR_ESTADO());

em.getTransaction().commit();

<a href="//em.getTransaction">//em.getTransaction</a>().begin();

<a href="//em.merge">//em.merge</a>(CADASTRO_USUARIO);

<a href="//em.persist">//em.persist</a>(ServletAlterarUsuario);

<a href="//em.getTransaction">//em.getTransaction</a>().commit();
em.close();

System.out.println("usuário alterado com sucesso!!");

}

porém retornou o seguinte erro

GRAVE: Servlet.service() for servlet [servlet.ServletAlterarUsuario] in context with path [/SISTEMA_ESCOLAR] threw exception

java.lang.NullPointerException

at com.cleiton.consultasAtualizarDeletar.ListarUsuarios.alterardados(ListarUsuarios.java:111)

at servlet.ServletAlterarUsuario.doPost(ServletAlterarUsuario.java:61)

at javax.servlet.http.HttpServlet.service(HttpServlet.java:650)
javaflex

Debuga pra saber exatamente onde está null. Aponta qual linha exata e qual objeto está null.

javaflex

Se mandar atualizar direto através do objeto que vem da requisição, funcionar vai, mas tem o perigo de sujar informações que não sejam atualizáveis por essa tela. Pode não ser o caso no momento, mas o sistema vira um campo minado. Assim como a preguiça do SELECT asterisco.

O ideal mesmo seria fazer update em SQL com os campos necessários pra funcionalidade em questão, mas pra turma que foge de SQL, HQL seria a saída mais eficiente e sob controle.

J

Sei que é meio antigo esse post, mas acho que posso ajudar.
Execute o comando find antes da transação, fora da transação.
Execute um print do conteúdo do objeto CADASTRO_USUARIO carregado, para saber se a propriedade id que está referenciada na classe/entidade está preenchida, se ela estiver vazia, será criado um novo registro.
Fiz um tutorial sobre JPA, ele é simples, por favor, veja se ajuda.
Seguem os links:
http://www.tidicas.com.br/?p=1864
http://www.tidicas.com.br/?p=130
http://www.tidicas.com.br/?p=319

Criado 29 de novembro de 2017
Ultima resposta 14 de dez. de 2020
Respostas 13
Participantes 5