HibernateTemplate.execute + Propagação de Transação

Olá pessoal,
ao utilizar apenas os métodos do hibernateTemplate, tais como: save em um mesmo método anotado com @Transactional, eles se comportam como o esperado.

@Transactional(rollbackFor = Exception.class)
public void salvar() {
Pai p = new Pai();
hibernateTemplate.save(p);

Filho f1 = new Filho();
f1.setPai(p);
Filho f2 = new Filho();
f2.setPai(p);
hibernateTemplate.save(f1);
hibernateTemplate.save(f2);
}

baseado no código acima, o sistema:

  1. salva o p
  2. salva f1
  3. salva f2

Porém, se eu precisar utilizar o hibernateTemplate.execute(new HibernateCallback() {…}) para setar o objeto Pai p, nos Filhos f1 e f2, conforme o codigo abaixo:

@Transactional(rollbackFor = Exception.class)
public void salvar() {
   Pai p = new Pai();
   hibernateTemplate.save(p);

   Filho f1 = new Filho();
   f1.setPai(p);
   Filho f2 = new Filho();
   f2.setPai(p);
   hibernateTemplate.save(f1);

   hibernateTemplate.execute(
				new HibernateCallback() {

	@Override
	public Object doInHibernate(Session session) throws HibernateException, SQLException {

        String sql = "update filho set pai = " +pai.getEntityid() + " where entityid = " + filho.getEntityid();
        Query q1 = (Query) session.createSQLQuery(sql);

	int q = q1.executeUpdate();
        return null;
   }
}

baseado no código acima, o sistema:

  1. salva f2 [color=red](por causa do callback ele tenta salvar o f2 sem seguir a ordem. Parece que cria um nova transação ignorando a atual, porém dá erro de constraint, pois o objeto pai ainda não foi persistido!)[/color]
  2. salva o p
  3. salva f1

Minha dúvida é: O que devo fazer pra o hibernateTemplate.execute(new HibernateCallback()… entenda que ele faz parte da mesma transação e que deve ser executado após os comandos anteriores?

Bem pessoal,

para forçar que os comandos anteriores sejam executados, utilizei o hibernateTemplate.flush. Então o código deveria ficar assim:

[code]@Transactional(rollbackFor = Exception.class)
public void salvar() {
Pai p = new Pai();
hibernateTemplate.save§;

Filho f1 = new Filho();
f1.setPai§;
Filho f2 = new Filho();
f2.setPai§;
hibernateTemplate.save(f1);

/**
*Flush all pending saves, updates and deletes to the database.
*
*Only invoke this for selective eager flushing, for example when JDBC code needs to see certain changes within the same transaction. Else, it is preferable to rely on auto-flushing at *transaction completion.
*
*/
hibernateTemplate.flush();

hibernateTemplate.execute(
new HibernateCallback() {

@Override
public Object doInHibernate(Session session) throws HibernateException, SQLException {

    String sql = "update filho set pai = " +pai.getEntityid() + " where entityid = " + filho.getEntityid();
    Query q1 = (Query) session.createSQLQuery(sql);

int q = q1.executeUpdate();
    return null;

}
}[/code]