2016-04-01 3 views
0

J'ai passé des heures à essayer de faire un rollback avec EJB. J'ai un contrôleur CDI où je veux enlever un objet. Quand j'essaye de retirer dans EJB j'obtiens une exception et j'essaye de faire le rollback, mais cela ne fonctionne pas. Tous les SQL qui ont été exécutés avec commit avant d'obtenir l'exception ne sont pas restaurés. Obviusly Ce n'est pas parce que j'obtiens une autre exception quand j'essaie de faire le rollback dans BMT. Sinon quand j'ai essayé avec CMT je reçois une exception d'hibernation mais j'obtiens les mêmes résultats que BMT.EJB Rollback ne fonctionne pas avec la transaction Container Management Transaction ou Bean Managament Transaction sur l'exception de validation

Mon contrôleur est

@Named 
@Stateful 
@ConversationScoped 
public class PRequerimientoConjuntoCertificacionesBean implements Serializable { 

    /** 
    * 
    */ 
    private static final long serialVersionUID = 1779474550283190942L; 

    @Inject 
    private Conversation conversation; 

    @PersistenceContext(type = PersistenceContextType.TRANSACTION) 
    private EntityManager entityManager; 

    @Inject 
    private DatosSesion datosSesion; 

    public void eliminarDocumento() { 
     // TODO hay que probarlo 
     DocumentoGeneradoSSCC documentoEliminar; 
     try { 
      documentoEliminar = (DocumentoGeneradoSSCC) daoBase 
        .getEntityById(DocumentoGeneradoSSCC.class, 
          10); 
      documentoSSCCDAOBean.removeDocumentoSSCC(documentoEliminar,entityManager); 
     } catch (Exception e) { 
      // TODO Auto-generated catch block 
      e.printStackTrace(); 
     } 
    } 
} 

Avec EJB BMT comme suit:

@Stateful 
@TransactionManagement(TransactionManagementType.BEAN) 
public class DocumentoSSCCDAOBean implements IDocumentoSSCCDAOBeanLocal { 

    @Resource 
    private UserTransaction userTran; 
    @PersistenceContext(type = PersistenceContextType.TRANSACTION) 
    private EntityManager entityManager; 

    @Override 
    @TransactionAttribute(TransactionAttributeType.REQUIRES_NEW) 
    public void removeDocumentoSSCC(
      DocumentoGeneradoSSCC documentoGeneradoSSCC, 
      EntityManager entityManager) { 
     // TODO hue probarlo 
     try { 
      userTran.begin(); 
      // Eliminamos recurso asignado 

      entityManager 
        .remove(entityManager.contains(documentoGeneradoSSCC) ? documentoGeneradoSSCC 
          : entityManager.merge(documentoGeneradoSSCC)); 
      userTran.commit(); 
     } catch (Exception e) { 
      try { 
       userTran.rollback(); 
      } catch (IllegalStateException e1) { 
       // TODO Auto-generated catch block 
       e1.printStackTrace(); 
      } catch (SecurityException e1) { 
       // TODO Auto-generated catch block 
       e1.printStackTrace(); 
      } catch (SystemException e1) { 
       // TODO Auto-generated catch block 
       e1.printStackTrace(); 
      } 
     } 
    } 
} 

et je reçois ce stacktrace

javax.transaction.RollbackException: ARJUNA016053: Impossible de validation de la transaction .

et quand j'essaie de faire rollback je reçois ce

java.lang.IllegalStateException: BaseTransaction.rollback - ARJUNA016074: aucune transaction!

J'ai standlone avec JTA = datasource vrai,

<datasource jta="true" jndi-name="java:jboss/datasources/ExampleDS" pool-name="ExampleDS" enabled="true" use-java-context="true"> 
    <connection-url>jdbc:h2:mem:test;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=FALSE</connection-url> 
    <driver>h2</driver> 
    <security> 
     <user-name>sa</user-name> 
     <password>sa</password> 
    </security> 
</datasource> 

mon persistence.xml est

<persistence-unit name="JusticiaGratuita" 
    transaction-type="JTA"> 
    <!-- <description>Forge Persistence Unit</description> --> 
    <provider>org.hibernate.ejb.HibernatePersistence</provider> 
    <jta-data-source>java:jboss/datasources/ExampleDS</jta-data-source> 
    <exclude-unlisted-classes>false</exclude-unlisted-classes> 

    <properties> 
     <property name="hibernate.connection.driver_class" value="${db.driver}" /> 
     <property name="hibernate.connection.url" value="${db.url}" /> 
     <property name="hibernate.connection.username" value="${db.user}" /> 
     <property name="hibernate.connection.password" value="${db.pass}" /> 
     <property name="hibernate.default_schema" value="${db.schema}" /> 

     <property name="hibernate.dialect" value="org.hibernate.dialect.Oracle10gDialect" /> 
     <property name="hibernate.hbm2ddl.auto" value="validate" /> 

     <property name="hibernate.query.substitutions" value="true 1, false 0,'SI' 1, 'NO' 0" /> 

     <property name="hibernate.cache.provider_class" value="org.hibernate.cache.EhCacheProvider" /> 
     <property name="hibernate.jdbc.batch_size" value="20" /> 
     <property name="hibernate.cache.use_second_level_cache" 
      value="true" /> 
     <property name="hibernate.cache.use_query_cache" value="false" /> 

     <property name="hibernate.show_sql" value="${db.showSql}" /> 
     <property name="hibernate.format_sql" value="true" /> 

     <property name="hibernate.connection.provider_class" 
      value="org.hibernate.service.jdbc.connections.internal.C3P0ConnectionProvider" /> 

     <property name="hibernate.c3p0.max_size" value="30" /> 
     <property name="hibernate.c3p0.min_size" value="5" /> 
     <property name="hibernate.c3p0.acquire_increment" value="1" /> 
     <property name="hibernate.c3p0.idle_test_period" value="3000" /> 
     <property name="hibernate.c3p0.max_statements" value="0" /> 
     <property name="hibernate.c3p0.timeout" value="0" /> 
     <property name="hibernate.c3p0.autocommit" value="false" /> 
    </properties> 

</persistence-unit> 

Vous pouvez voir plein stacktrace de mon erreur ici: http://pastebin.com/h17JD2xP

I w J'apprécierais toute aide pour faire marche arrière et résoudre mes problèmes.

Cordialement

+1

Eh bien, il est déjà un peu contradictoire d'avoir un attribut de transaction géré par conteneur (REQUIRES_NEW) lorsque les transactions gérées par bean sont en place. Mais je suppose que le conteneur pourrait ignorer cela. – Gimby

+0

Eh bien, l'attribut de transaction géré par conteneur que j'utilise est OBLIGATOIRE, mais l'exemple que je montre est une transaction gérée par Bean. –

Répondre

0

Enfin, je résous mon problème. Je recevais cette exception parce qu'avant d'effectuer la restauration, j'exécutais commit, donc il est impossible d'exécuter rollback après validation car ces deux sont exclusifs l'un de l'autre. Cause de ce que je n'ai pas eu de transaction, parce que commettre le fermer et quand rollback exécuter il n'y avait aucune transaction.

java.lang.IllegalStateException: BaseTransaction.rollback - ARJUNA016074: aucune transaction!

Enfin, j'ai décidé de faire de cette façon avec CMT.

@TransactionManagement(TransactionManagementType.CONTAINER) 
@Stateless 
public class DocumentoSSCCServiceBean implements IDocumentoSSCCServiceBeanLocal { 

    @EJB 
    private IDaoBase daoBase; 

    @PersistenceContext(unitName = "JusticiaGratuita", type = PersistenceContextType.TRANSACTION) 
    private EntityManager entityManager; 

    @Resource 
    private EJBContext ejbContext; 

    @Override 
    @TransactionAttribute(TransactionAttributeType.REQUIRED) 
    public void removeDocumentoSSCC(Long documentoGeneradoSSCC) 
      throws RollbackSajgException { 
     try { 
      // Buscamos el documento a eliminar 
      DocumentoGeneradoSSCC docu = (DocumentoGeneradoSSCC) daoBase 
        .getEntityById(DocumentoGeneradoSSCC.class, 
          documentoGeneradoSSCC); 

      entityManager.remove(docu); 
     } catch (Exception e) { 

      ejbContext.setRollbackOnly(); 
      throw new RollbackSajgException(); 

     } 
    } 
} 

J'espère que cela pourrait aider quelqu'un.