[RESOLVIDO] Spring + Hibernate - problema com controle de transações

Durante um teste com JUnit tento incluir no banco de dados uma campanha e logo após incluo um agendamento que possui uma FK para essa campanha. Nesse momento recebo o erro que a campanha especificada não foi encontrada…
Se puderem me ajudar agradeço!

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations={"/META-INF/beans.xml"})
public class AgendamentoFacadeTest {
	@Autowired
	private AgendamentoFacade agendamentoFacade;
	@Autowired
	private CampanhaFacade campanhaFacade;
	
	@Test
	public void testGeraAgendamentoAtravesDeCampanhaDBM(){
		String codCampanha = "9999";
		
		CampanhaDBM campanhaDBM = campanhaFacade.obtemCampanhaPorCodigo(codCampanha);
		Campanha campanha = new Campanha(campanhaDBM);
		campanha = campanhaFacade.salvar(campanha);
		Integer template = 1;
		Integer sender = 1;
		String nomeAgendamento = "Um nome de agendamento";
		String nomeRemetente = "Um nome legal de remetente";
		String enderecoParaResposta = "endereco@paraResposta.com";
		
		Agendamento agendamento = new Agendamento(campanha, template, sender, nomeAgendamento, nomeRemetente, enderecoParaResposta);
		
		Agendamento ag = agendamentoFacade.salvar(agendamento); //<-- aqui ocorre o erro
		
		Assert.assertNotNull("O agendamento não foi persistido.", ag);
	}
}

[code]@Repository
public class BaseDAO {
private JpaTemplate jpaTemplate;

@PersistenceUnit
public void setJpaTemplate(EntityManagerFactory emf) {
	EntityManager em = emf.createEntityManager();
	em.setFlushMode(FlushModeType.COMMIT);
	this.jpaTemplate = new JpaTemplate(em);
}

protected Session getSession(){
	
	return (Session) jpaTemplate.getEntityManager().getDelegate();
}

}[/code]

[code]@Service
public class CampanhaFacadeImpl implements CampanhaFacade {
@Autowired
private CampanhaDAO campanhaDAO;

@Override @Transactional
public <T> T salvar(T campanha) {
	return campanhaDAO.salvar(campanha);
}

}[/code]

@Repository
public class CampanhaDAOImpl extends BaseDAO implements CampanhaDAO {
	public <T> T salvar(T campanha) {
		campanha = (T) getSession().merge(campanha);
		return campanha;
	}

}
@Service
public class AgendamentoFacadeImpl implements AgendamentoFacade {
	@Autowired
	private AgendamentoDAO agendamentoDAO;

	@Override @Transactional
	public Agendamento salvar(Agendamento agendamento) {
		return agendamentoDAO.salvar(agendamento);
	}

}
@Repository
public class AgendamentoDAOImpl extends BaseDAO implements AgendamentoDAO{

	@Override
	public Agendamento salvar(Agendamento agendamento) {
		return (Agendamento) getSession().merge(agendamento);
	}

}

[code]

<context:component-scan base-package="com.projeto" />
  
<!-- bean post-processor for JPA annotations -->
<bean class="org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor"/>	

<bean id="entityManagerFactory" class="com.projeto.dao.creator.JPAEntityManagerCreator">
</bean>

<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager"
  p:entityManagerFactory-ref="entityManagerFactory"/>

<tx:annotation-driven/>

[/code]

Faça um flush antes de chamar o segundo salvar.

obrigado jakefrog, não ocorreu mais o erro.
existe um meio do spring ou hibernate controlar isso? ou nesse caso o unico meio é utilizando o flush manual mesmo?

Achei estranho também que se eu não colocar um flush depois de salvar um agendamento, essa informação não é gravada no banco de dados… Existe alguma configuração que esqueci de fazer e por esse motivo esses dados não são gravados?

Cara, infelizmente não tenho como te ajudar com as Transações em Spring.

Não entendo desse cara.

Uma coisa eu sei, que tem como o servidor controlar a transação ou sua aplicação fazer esse trabalho sujo.

Não sei como você arquitetou isso em seu sistema, mas valeria a pena estudar melhor transações no Spring. [=

Irei pesquisar mais sobre o assunto, muito obrigado pela ajuda!

Demorou um tempo mas descobri o problema.

Estava injetando um EntityManagerFactory para me aproveitar do scan da JPA nas classes entity, e usando o getDelegate para trabalhar com o Hibernate, e é nessa hora que o Spring parava de controlar a transação. Para que o controle de transações do Spring funcione adequadamente tenho duas alternativas, injetar diretamente um EntityManager e utilizar JPA na minha aplicação, ou se quiser continuar a utilizar o Hibernate, devo injetar uma SessionFactory e definir no xml as classes da minha aplicação.

Com essa solução antes de efetuar o commit o Spring executa um flush resolvendo meu problema.