Teste com @Rollback não funciona

Estou fazendo uns testes integrados com HSQLDB em memória, utilizando spring.
No meu teste eu coloco, além da anotação @Test, @Rollback ou @Rollback(true), mas oq é inserido no banco não está sendo apagado.

Eu fiz um teste:

@Test
@Transactional
@Rollback
public void testSalvaUsuario(){…}

Dessa forma funcionou.
Mas o @Rollback não deveria funcionar sem outra anotação ?
Alguem sabe me explicar oq acontece ?

Você precise usar a seguinte anotação para os testes de integração com o Spring:
@RunWith(SpringJUnit4ClassRunner.class).
@ContextConfiguration({ “/test-datasource-context.xml”})

test-datasource-context.xml : aqui ficaria suas configurações do HSQLDB.

Com isso o Spring se encarrega do trabalho de rollback assim como aproveitar a carga do contexto para os
proximos testes.

Abraço!

Mas é isso q faço…

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration({“classpath:/testApplicationContext.xml”})
@ActiveProfiles(“test”)
public abstract class AbstractControllerTest {

}

public class AppControllerTest extends AbstractControllerTest

É o seguinte, quando o Spring carrega o contexto de testes ele o faz uma unica vez e pelo que estou vendo a carga no banco se dá uma unica vez. Desta forma você terá que informar ao spring explicitamente que você não deseja comitar. Você já esta fazendo com o @Rollback, outra forma de fazer isso seria usar os metodos do
cliclo de vida do seu framework de teste para fazer a carga dos dados a cada teste, porem isso iria impactar no desempenho.

Você pode adicionar a sua AbstractControllerTest a anotação @TransactionConfiguration(defaultRollback = true) ou manter a configuração que você já vem usando visto que esta funcionando.

Não sei se respondi a sua pergunta mas foi isso que entendi!

abraço!

Agora coloquei o @TransactionConfiguration(defaultRollback = true) e não funcionou tb… hehehe
O jeito é deixar os testes com as duas anotações:

@Transactional
@Rollback

Eu só estranho pq na documentação o exemplo usa o @Rollback sem nenhuma outra anotação.
Se eu não colocar o @Transactional em cada teste, não funfa.

http://static.springsource.org/spring/docs/3.1.1.RELEASE/spring-framework-reference/htmlsingle/spring-framework-reference.html#integration-testing-annotations-spring

O @Transactional é uma anotação que diz ao Spring quando iniciar a transação, quando você coloca ela na classe vc diz que a partir de qualquer metodo chamado
na classe mencionada será iniciada uma trasação, portanto quando se chama o DAO/Servico a partir desta classe com o @Transactional o proxy do spring identificará que já existe uma trasação aberta e irá usar essa transação no DAO/Servico que foi chamado, isso se chama Propagação transacional, dependendo da configuração irá herdar a transação ou criará uma nova, tudo vai depender do perfil trasacional.

Voltando a história do @Trasactional, se vc não adicionar isso na sua classe de teste o proxy do spring ao receber a chamada do seu teste ao DAO/Service irá identificar que não existe uma trasação corrente, então ele criará uma nova e quando o metodo do seu DAO ou Serviço retornar o Spring irá fechar a transação, ou seja, você já não poderá usar o lazy do hibernate porque essa transação já foi fechada.

Nos testes de exemplo do Spring ele usa o @Trasactional na classe e usa o @RollBack(true) no metodo, pois entende-se que nos outro metodos ele quer que seja feito o commit, quando colocado @Rollback na classe endende-se que será realizado rollback para todos os metodos da classe anotada, capti?

Abraço!

Então…
Eu fiz o seguinte nos meus métodos, no service.

@Transactional
public void atualizaUsuario(Usuario usuario) {
entityManager.merge(usuario);
}

Mas não testei com @Transactional direto na classe, como vc disse…
Vou testar e posto aqui.

Vlw a ajuda !

Edit:
Testei aqui.
Ééé… não funcionou com @Transactional direto na classe

Bem… deixa rolar…

Edit 2:

Qd vc disse q o spring coloca @Transactional na classe, eu pensei errado e coloquei na classe service ao invés de colocar na classe de test.
Colocando na classe de test funciona sim :slight_smile:

Não faz sentido ter um @Rollback sem iniciar uma transação, tem que se ligar que as vezes os caras se passam nos exemplos.

Eu já peguei nome de atributo do JSF errado no J2EE tutorial.

Como diria Krust o palhaço: “As pessoas são porcas”

ahahahah

Isso ai rapaz, bom que funcionou se precisar é só postar!

falows!!!

[quote=thiago.correa]Não faz sentido ter um @Rollback sem iniciar uma transação, tem que se ligar que as vezes os caras se passam nos exemplos.

Eu já peguei nome de atributo do JSF errado no J2EE tutorial.

Como diria Krust o palhaço: “As pessoas são porcas”

ahahahah[/quote]

A questão não é essa.
Transação existia, mas não no teste e sim no service.

Eu imaginava q o @Rollback iria desfazer oq foi feito na transação do service, mas não é oq acontece.
Precisa usar o @Transactional no teste tb.