Boa tarde pessoal, veja se alguém pode me ajudar.
Rodanto o contexto web normamalmente com:
@PersistenceContext
private EntityManager entityManager;
Isto aí está dentro de um dao genérico (percebam que o contextType do @PersistenceContext é o default, ou seja: TRANSACTION).
Então tudo roda certinho (lazy) na web, pois estou usando o filtro openEntityManagerInViewFilter.
Ok, só que eu preciso realizar alguns testes fora da web, e aí recebo aquela famigerada:
18:41:57,753 ERROR LazyInitializationException:42 - failed to lazily initialize a collection of role
Esta todo mundo já conhece…
Então, eu sei como contornar isto nos meus testes, vou lá no meu dao e mudo o contextType para EXTENDED, e aí todos os testes passam. Beleza…
Só que isto se torna um saco, toda hora ter que mudar o valor do contextType, além do que me parece uma má prática de tudo que tenho aprendido.
Então eu vi uma classe dessa por aí:
[code]import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import junit.framework.TestCase;
import org.springframework.context.ApplicationContext;
import org.springframework.orm.jpa.EntityManagerFactoryUtils;
import org.springframework.orm.jpa.EntityManagerHolder;
import org.springframework.transaction.support.TransactionSynchronizationManager;
import br.mil.eb.dgp.avaliacao.test.SpringContextLoad;
public abstract class BaseTest extends TestCase {
private ApplicationContext context = null;
private EntityManagerFactory entityManagerFactory;
public BaseTest(final String name) {
super(name);
}
@Override
protected void setUp() throws Exception {
super.setUp();
this.context = SpringContextLoad.getInstance(this.getContextFiles()).getContext();
entityManagerFactory = (EntityManagerFactory) context.getBean("entityManagerFactory");
EntityManager entityManager = EntityManagerFactoryUtils.getTransactionalEntityManager(entityManagerFactory);
TransactionSynchronizationManager.bindResource(entityManagerFactory, new EntityManagerHolder(entityManager));
}
@Override
protected void tearDown() throws Exception {
super.tearDown();
EntityManagerHolder entityManagerHolder = (EntityManagerHolder) TransactionSynchronizationManager
.unbindResource(entityManagerFactory);
EntityManagerFactoryUtils.closeEntityManager(entityManagerHolder.getEntityManager());
context = null;
}
protected Object getBean(final String beanName) {
if (null == beanName || 0 == beanName.trim().length())
throw new IllegalArgumentException("Nome do bean não informado.");
return this.context.getBean(beanName);
}
protected String[] getContextFiles() {
return new String[] { "application.xml" };
}
protected ApplicationContext getApplicationContext() {
return this.context;
}
}[/code]
É exatamente isto que eu preciso para que meus testes passem sem eu ter que ficar mudando o valor do contextType. Só que eu não tenho a mínima noção de como usar ela.
Então copiei o código do método setUp da classe acima e coloquei dentro do meu teste. O rsultado é que o entityManager retorna nulo, no entanto, meu context.xml possui os benas transactionManager e transactionInterceptor (lembre-se, rodando na web tudo funciona normamalmente - está ocorrendo transação e tudo o mais…).
Pessoal, me ajudem aí, tem dois dias que estou tentando desenvolver isto, o chefe (na verdade é a chefe), vai me matar, rs rsrs…
Obrigado.