2 Replies Latest reply on Jun 8, 2007 2:09 PM by Gustavo J

    Problem with @Transactional

    Gustavo J Newbie

      Friends
      I have the following situation.
      I have an interface that implements a simple CRUD with the methods annotated with @Transactional(REQUIRED).
      The class that implements this interface uses a session of the Hibernate with corresponding DAO interface. Until now, no mystery.
      The problem occurs when I use the instance in backing bean. The transaction does not finish after method execution,
      and I can't capture exceptions generated by the DataBase.

      What kind of configuration do I need to do for application finish the transaction correctly, after method execution?

      Thank's.

      Below examples of the codes


      GenericDAO

       public interface GenericDAO<T, PK extends Serializable> {
       @Transactional(TransactionPropagationType.MANDATORY)
       public T save(T o) throws Exception;
      
       @Transactional(TransactionPropagationType.MANDATORY)
       public void delete(T o) throws Exception;
       }
      



      GenericDAOImpl
       public class GenericDAOImpl<T, PK extends Serializable> implements GenericDAO<T, PK> {
       public T save(T o) throws Exception {
       return o;
       }
      
       public void delete(T o) throws Exception {
       session.delete(o);
       }
       }
      



      BusinessManager
       public interface BusinessManager<T, PK extends Serializable> {
       @Transactional(value = TransactionPropagationType.REQUIRED)
       public void save(T object) throws BusinessException;
      
       @Transactional(value = TransactionPropagationType.REQUIRED)
       public void remove(PK id) throws BusinessException;
       }
      



      BusinessManagerImpl
       public class BusinessManagerImpl<T, PK extends Serializable> implements BusinessManager<T, PK> {
       public void save(T object) throws BusinessException {
       try {
       genericDAO.saveOrUpdate(object);
       } catch (Exception dae) {
       throw new BusinessException(dae);
       }
       }
      
       public void remove(PK id) throws BusinessException {
       try {
       genericDAO.remove(id);
       } catch (Exception dae) {
       throw new BusinessException(dae);
       }
       }
       }
      



      spring-beans-dao.xml
       <bean id="projetoDAO" class="br.com.develop.fw.persistence.GenericDAOImpl">
       <property name="clazz" value="br.com.develop.ponto.model.Projeto" />
       <seam:component/>
       </bean>
      



      spring-beans-business.xml
       <bean id="projetoManager" class="br.com.develop.fw.business.BusinessManagerImpl" scope="singleton">
       <property name="genericDAO" ref="projetoDAO"/>
       <seam:component/>
       </bean>
      



      ProjetoAction (Backing Bean)
       @Name("projetoAction")
       @Scope(ScopeType.CONVERSATION)
       public class ProjetoAction extends AbstractBackingBean<Projeto> implements Serializable {
       @In("projetoManager")
       private BusinessManager<Projeto, Serializable> projetoManager;
      
       @Restrict
       public void delete() {
       try {
       log.debug("will be delete...");
       projetoManager.remove(selected.getId());
       log.debug("deleted??");
       FacesMessages.instance().add("{0} has been removed.", new Object[] { selected.getNome() });
       } catch (Throwable e) {
       addMessage("Faild to remove");
       }
       }
      



      Exception
      2007-06-06 17:03:43,312 DEBUG [br.com.develop.ponto.action.ProjetoAction:79:<delete>] - [admin] will be delete...
      2007-06-06 17:03:43,312 DEBUG [br.com.develop.ponto.action.ProjetoAction:81:<delete>] - [admin] deleted??
      2007-06-06 17:03:44,921 DEBUG [org.hibernate.SQL:401:<log>] - [admin] delete from PROJETOS where ID=?
      Hibernate: delete from PROJETOS where ID=?
      2007-06-06 17:03:44,984 WARN [org.hibernate.util.JDBCExceptionReporter:77:<logExceptions>] - SQL Error: 0, SQLState: 23503
      2007-06-06 17:03:44,984 ERROR [org.hibernate.util.JDBCExceptionReporter:78:<logExceptions>] - [admin] ERROR: update or delete on table "projetos" violates foreign key constraint "fk_projeto" on table "importacao_funcionario"
       Detalhe: Key (id)=(1) is still referenced from table "importacao_funcionario".
      2007-06-06 17:03:45,000 ERROR [org.hibernate.event.def.AbstractFlushingEventListener:301:<performExecutions>] - [admin] Could not synchronize database state with session
      org.hibernate.exception.ConstraintViolationException: could not delete: [br.com.develop.ponto.model.Projeto#1]
       at org.hibernate.exception.SQLStateConverter.convert(SQLStateConverter.java:71)
       at org.hibernate.exception.JDBCExceptionHelper.convert(JDBCExceptionHelper.java:43)
       at org.hibernate.persister.entity.AbstractEntityPersister.delete(AbstractEntityPersister.java:2541)
       at org.hibernate.persister.entity.AbstractEntityPersister.delete(AbstractEntityPersister.java:2697)
      


        • 1. Re: Problem with @Transactional
          Christian Bauer Master

          You should use TransactionalSeamPhaseListener for JSF. It begins and commits transactions.

          • 2. Re: Problem with @Transactional
            Gustavo J Newbie

            Yes, I using this.
            The transaction works, but not correctly.

            In this code.

            try {
             log.debug("will be delete...");
             projetoManager.remove(selected.getId()); <---- generates a exception
             log.debug("deleted??"); <--- after execption... this continue...
             FacesMessages.instance().add("{0} has been removed.", new Object[] { selected.getNome() });
            } catch (Throwable e) {
             addMessage("Faild to remove"); <--- not printed
            }
            


            this is my faces-config
            <faces-config>
             <application>
             <view-handler>
             org.jboss.seam.ui.facelet.SeamFaceletViewHandler
             </view-handler>
             <el-resolver>org.jboss.seam.jsf.SeamELResolver</el-resolver>
             <locale-config>
             <default-locale>pt_BR</default-locale>
             <supported-locale>pt_BR</supported-locale>
             <supported-locale>en_US</supported-locale>
             </locale-config>
             <message-bundle>MessageBundle</message-bundle>
             </application>
            
             <lifecycle>
             <phase-listener>
             org.jboss.seam.jsf.TransactionalSeamPhaseListener
             </phase-listener>
             </lifecycle>
            </faces-config>