Estou tentando fazer um update em uma tabela usando o comando merge do JPA porém esta dando erro… estou chamando o merge aqui…
public boolean update(Programa prog) {
em.getTransaction();
em.getTransaction().begin();
try {
em.merge(prog);
em.getTransaction().commit();
return true;
//em.find(arg0, arg1)
}
catch (Exception e){
e.printStackTrace();
em.getTransaction().rollback();
return false;
}
}
e esse é o erro que esta ocorrendo
javax.persistence.RollbackException: Error while commiting the transaction
at org.hibernate.ejb.TransactionImpl.commit(TransactionImpl.java:71)
at br.com.is.ishistorico.dao.ProgramasDaoImpl.update(ProgramasDaoImpl.java:55)
at br.com.is.ishistorico.gui.JPanelSEProgramas$4.actionPerformed(JPanelSEProgramas.java:273)
at javax.swing.AbstractButton.fireActionPerformed(Unknown Source)
at javax.swing.AbstractButton$Handler.actionPerformed(Unknown Source)
at javax.swing.DefaultButtonModel.fireActionPerformed(Unknown Source)
at javax.swing.DefaultButtonModel.setPressed(Unknown Source)
at javax.swing.plaf.basic.BasicButtonListener.mouseReleased(Unknown Source)
at java.awt.Component.processMouseEvent(Unknown Source)
at javax.swing.JComponent.processMouseEvent(Unknown Source)
at java.awt.Component.processEvent(Unknown Source)
at java.awt.Container.processEvent(Unknown Source)
at java.awt.Component.dispatchEventImpl(Unknown Source)
at java.awt.Container.dispatchEventImpl(Unknown Source)
at java.awt.Component.dispatchEvent(Unknown Source)
at java.awt.LightweightDispatcher.retargetMouseEvent(Unknown Source)
at java.awt.LightweightDispatcher.processMouseEvent(Unknown Source)
at java.awt.LightweightDispatcher.dispatchEvent(Unknown Source)
at java.awt.Container.dispatchEventImpl(Unknown Source)
at java.awt.Window.dispatchEventImpl(Unknown Source)
at java.awt.Component.dispatchEvent(Unknown Source)
at java.awt.EventQueue.dispatchEvent(Unknown Source)
at java.awt.EventDispatchThread.pumpOneEventForFilters(Unknown Source)
at java.awt.EventDispatchThread.pumpEventsForFilter(Unknown Source)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown Source)
at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
at java.awt.EventDispatchThread.run(Unknown Source)
Caused by: org.hibernate.exception.SQLGrammarException: Could not execute JDBC batch update
at org.hibernate.exception.SQLStateConverter.convert(SQLStateConverter.java:90)
at org.hibernate.exception.JDBCExceptionHelper.convert(JDBCExceptionHelper.java:66)
at org.hibernate.jdbc.AbstractBatcher.executeBatch(AbstractBatcher.java:275)
at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:266)
at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:169)
at org.hibernate.event.def.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:321)
at org.hibernate.event.def.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:50)
at org.hibernate.impl.SessionImpl.flush(SessionImpl.java:1028)
at org.hibernate.impl.SessionImpl.managedFlush(SessionImpl.java:366)
at org.hibernate.transaction.JDBCTransaction.commit(JDBCTransaction.java:137)
at org.hibernate.ejb.TransactionImpl.commit(TransactionImpl.java:54)
... 27 more
Caused by: java.sql.BatchUpdateException: Entrada em lote 0 delete from Programa_ProgramaHistorico where Programa_progId=24 foi abortada. Chame getNextException para ver a causa.
at org.postgresql.jdbc2.AbstractJdbc2Statement$BatchResultHandler.handleError(AbstractJdbc2Statement.java:2537)
at org.postgresql.core.v3.QueryExecutorImpl.processResults(QueryExecutorImpl.java:1328)
at org.postgresql.core.v3.QueryExecutorImpl.execute(QueryExecutorImpl.java:351)
at org.postgresql.jdbc2.AbstractJdbc2Statement.executeBatch(AbstractJdbc2Statement.java:2674)
at org.hibernate.jdbc.BatchingBatcher.doExecuteBatch(BatchingBatcher.java:70)
at org.hibernate.jdbc.AbstractBatcher.executeBatch(AbstractBatcher.java:268)
... 35 more
java.lang.IllegalStateException: Transaction not active
at org.hibernate.ejb.TransactionImpl.rollback(TransactionImpl.java:82)
at br.com.is.ishistorico.dao.ProgramasDaoImpl.update(ProgramasDaoImpl.java:61)
at br.com.is.ishistorico.gui.JPanelSEProgramas$4.actionPerformed(JPanelSEProgramas.java:273)
at javax.swing.AbstractButton.fireActionPerformed(Unknown Source)
at javax.swing.AbstractButton$Handler.actionPerformed(Unknown Source)
at javax.swing.DefaultButtonModel.fireActionPerformed(Unknown Source)
at javax.swing.DefaultButtonModel.setPressed(Unknown Source)
at javax.swing.plaf.basic.BasicButtonListener.mouseReleased(Unknown Source)
at java.awt.Component.processMouseEvent(Unknown Source)
at javax.swing.JComponent.processMouseEvent(Unknown Source)
at java.awt.Component.processEvent(Unknown Source)
at java.awt.Container.processEvent(Unknown Source)
at java.awt.Component.dispatchEventImpl(Unknown Source)
at java.awt.Container.dispatchEventImpl(Unknown Source)
at java.awt.Component.dispatchEvent(Unknown Source)
at java.awt.LightweightDispatcher.retargetMouseEvent(Unknown Source)
at java.awt.LightweightDispatcher.processMouseEvent(Unknown Source)
at java.awt.LightweightDispatcher.dispatchEvent(Unknown Source)
at java.awt.Container.dispatchEventImpl(Unknown Source)
at java.awt.Window.dispatchEventImpl(Unknown Source)
at java.awt.Component.dispatchEvent(Unknown Source)
at java.awt.EventQueue.dispatchEvent(Unknown Source)
at java.awt.EventDispatchThread.pumpOneEventForFilters(Unknown Source)
at java.awt.EventDispatchThread.pumpEventsForFilter(Unknown Source)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown Source)
at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
at java.awt.EventDispatchThread.run(Unknown Source)
se alguém pouder me ajudar…
no seu persistence.xml a propriedade auto commit está como false?
o persistence.xml não possui essa property
<?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="pu1">
<provider>org.hibernate.ejb.HibernatePersistence</provider>
<class>br.com.is.ishistorico.model.Programa</class>
<class>br.com.is.ishistorico.model.ProgramaHistorico</class>
<properties>
<property name="hibernate.connection.driver_class" value="org.postgresql.Driver"/>
<property name="hibernate.connection.username" value="postgres"/>
<property name="hibernate.connection.password" value="********"/>
<property name="hibernate.connection.url" value="jdbc:postgresql://localhost:5432/ISHistorico"/>
<property name="hibernate.dialect" value="org.hibernate.dialect.PostgreSQLDialect"/>
<property name="hibernate.show_sql" value="true"/>
</properties>
</persistence-unit>
</persistence>
arrumei aqui o auto commit e deu o mesmo erro…tanto como “false” como “true”
Em relação ao seu código vc poderia dar esta melhorada:
public void update(Program prog) {
try {
EntityTransaction entityTransaction = entityManager.getTransaction();
entityTransaction.begin();
entityManager.merge(prog);
entityTransaction.commit();
} catch (PersistenceException e) {
throw new PersistenceException(e);
}
}
Em relação ao erro, seu EntityManager está sendo criado a partir de um EntityManagerFactory ou está sendo injetado ?
Poste essa classe para o pessoal poder te ajudar melhor…
simmm…é um EntityManagerFactory
public class ProgramasDaoImpl<T> extends DAOImplHb {
private static EntityManagerFactory emf;
private EntityManager em;
public ProgramasDaoImpl(){
emf = Persistence.createEntityManagerFactory("pu1");
em = emf.createEntityManager();
}
public boolean create(Programa prog) {
em.getTransaction().begin();
try {
em.persist(prog);
em.getTransaction().commit();
return true;
//em.find(arg0, arg1)
}
catch (Exception e){
e.printStackTrace();
em.getTransaction().rollback();
return false;
}
}
public boolean update(Programa prog) {
em.getTransaction();
em.getTransaction().begin();
try {
em.merge(prog);
em.getTransaction().commit();
return true;
//em.find(arg0, arg1)
}
catch (Exception e){
e.printStackTrace();
em.getTransaction().rollback();
return false;
}
}
public static ArrayList<Programa> listarProgramas() {
ArrayList<Programa> lista = new ArrayList<Programa>();
ProgramasDaoImpl dao = new ProgramasDaoImpl();
lista = dao.loadAllPrograma();
return lista;
}
public ArrayList<Programa> loadAllPrograma() throws InfrastructureException {
ArrayList<Programa> c = new ArrayList<Programa>();
try {
em.getTransaction();
Query q = em.createQuery("SELECT progId, nomePrograma, modulo, descricao FROM Programa" );
ArrayList<Object[]> resultado = (ArrayList<Object[]>) q.getResultList();
Programa programa = null;
for (Object[] objects : resultado) {
programa = new Programa();
programa.setProgId((Integer)objects[0]);
programa.setNomePrograma((String)objects[1]);
programa.setModulo((Integer)objects[2]);
programa.setDescricao((String)objects[3]);
c.add(programa);
}
System.out.println(c);
return c; }
catch (Exception e){
e.printStackTrace();
em.getTransaction().rollback();
return null;}
}
public ArrayList<Programa> loadProgramaByProgId(int progId) throws InfrastructureException {
ArrayList<Programa> c = new ArrayList<Programa>();
try {
em.getTransaction();
Query q = em.createQuery("SELECT progId, nomePrograma, modulo, descricao FROM Programa where progId = "+progId );
ArrayList<Object[]> resultado = (ArrayList<Object[]>) q.getResultList();
Programa programa = null;
for (Object[] objects : resultado) {
programa = new Programa();
programa.setProgId((Integer)objects[0]);
programa.setNomePrograma((String)objects[1]);
programa.setModulo((Integer)objects[2]);
programa.setDescricao((String)objects[3]);
c.add(programa);
}
System.out.println(c);
return c; }
catch (Exception e){
e.printStackTrace();
em.getTransaction().rollback();
return null;}
}
}
Humm… Já que é criado por um EnityManagerFactory faça um teste de trocar o tipo de transação no persistence.xml, para ver se continua o mesmo erro…
<persistence-unit name="pu1" transaction-type="RESOURCE_LOCAL">
</persistence-unit>
sim…continua o mesmo erro
=/
O persist do entity manager dá o mesmo problema ou so ocorrre com o merge ?
só no Merge…o Persist funcionou de boa…
Meio estranho porque a froma com que os dois estão implementados está muito parecida…
1 - Tem apenas uma diferença no seu merge, retire aquele em.getTransaction(); da linha 29 , meio redundante (se possível otimize o método da forma que eu postei no primeiro post)…
2 - Se mesmo assim não funcionar debuge os dois métodos para ver se no merge existe algum comportamento diferente do persist, verifique principalmente o getTransaction()
eu retirei o em.getTransaction(); e fiz o debug…os dois se comportram da mesma maneira…porém o merge continua com o mesmo erro…
Então se no mesmo método que você faz o merge vc mudar para persist ele funciona?
hahahahahhaha… Fala sério…
sera que pode ter algo a ver com o mapeamento nas classes? as relações e td mais?
mais dai não estaria inserindo com o persist tb né…
É estranho pq ambos merge e persist exigem que exista uma transação aberta para fazer a ação de persistência…Tinha que dar o mesmo erro no persist tbm…
Outra coisa se fosse um erro específico do merge(pela exceção que vc postou não é o caso) a exceção seria outra, seria mais específica…
Não sei se vc pode fazer isso mas eu mudaria seu projeto para ter as transações gerenciadas pelo container, além de ficar com o código mais limpo (sem ter que ficar abrido e comitando transações) vc não tem estes tipos de dores de cabeça que vc está tendo…
pois é o projeto eu não posso mudar por ser um padrão da empresa…
a solução é continuar tentando mesmo
Quando vc utiliza o merge ele da erro em ambas as situações ? Quando tenta gravar uma entidade do zero ou quando tenta atualizar uma já existente ?
Em certos casos é interessante rever os padrões para ter aplicações mais flexíveis e mais fáceis de se dar manutenção…E ter transações gerenciadas no braço pode gerar estes problemas que vc está tendo e muitos outros…