Problem with @Transactional
gustajz Jun 6, 2007 4:55 PMFriends
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)