Acesso ao BD num Listener via IoC (Spring)

61 views
Skip to first unread message

Charles

unread,
Aug 5, 2011, 8:44:28 AM8/5/11
to jav...@googlegroups.com
Bom dia pessoal.

Estou precisando da ajuda dos colegas experientes...

Tenho uma aplicação
(JSF+Richfaces+JPA+Hibernate+Spring+SpringSecurity) em produção
"redodinha" rodando q uma blz, dá até orgulho. Agora preciso criar um
Listener (alias já o fiz com jdbc) q faz buscas no BD todos os dias de
madrugada (01:00) e trata o resultado para fazer consultas num site
de internet e depois atualizar o BD conforme tais consultas.

Estou tentando fazer o acesso do listener ao BD por IoC utilizando o
Spring mas ñ funciona, sempre dá q o entityManager ñ foi instanciado
(NullPointerException); de fato constatei "debugando" q o Spring ñ
cria o objeto como esperava.

Tenho pouca experiência nas tecnologias que utilizo nesta aplicação
creio q por isso ñ estou identificando o problema. Meus DAOs estão
todos funcionando (td anotado com @Transation, @PersistenceContext) e
estou fazendo a msm coisa para o DAO do listener mas ñ funfa.

Por favor, alguém sabe se há alguma restrição da utilização de IoC num
listener e/ou poderia me indicar um caminho a seguir?

Muito obrigado tds.
[]'s
t++
Minero

--
Alice: Pode me dizer, por favor, por que caminho devo ir?
Gato: Isto tem muito a ver com o lugar onde queres chegar.
Alice: Qualquer lugar.
Gato: Neste caso qualquer caminho serve.
(ALICE NO PAÍS DAS MARAVILHAS, Lewis Carol)

Bruno Maomeh

unread,
Aug 5, 2011, 9:07:55 AM8/5/11
to jav...@googlegroups.com
você já pesquisou sobre o quartz? ele é o agendador do spring.. creio que se encaixe bem no seu cenário..


--
Você recebeu esta mensagem por que é membro do  Javasf
http://groups.google.com/group/javasf

Conheça também o Java Brazil: http://groups.google.com/group/thejavabrazil



--
Bruno Maomeh
   http://brunomaomeh.wordpress.com

Rafael Ponte

unread,
Aug 5, 2011, 1:08:17 PM8/5/11
to jav...@googlegroups.com
Se estiver utilizando o Spring 3.x você não precisa do Quartz, pois ele já tem um schedule próprio que funciona para maioria dos casos!

2011/8/5 Bruno Maomeh <bruno...@gmail.com>



--
Rafael Ponte
http://www.rponte.com.br

Charles

unread,
Aug 5, 2011, 2:40:35 PM8/5/11
to jav...@googlegroups.com
Obrigado pelas resposta Rafael e Bruno.

Estou analisando as suas sugestões mas vcs sabem me dizer onde estou
errando no Listener?

[]'s
t++
Minero

2011/8/5 Rafael Ponte <rpo...@gmail.com>:

Bruno Maomeh

unread,
Aug 5, 2011, 3:13:20 PM8/5/11
to jav...@googlegroups.com
como você está fazendo pra injetar teus beans do spring no listener?

Charles

unread,
Aug 8, 2011, 9:54:30 AM8/8/11
to jav...@googlegroups.com
Desculpe-me a demora e obrigado por tentar me ajudar Bruno.

Basicamente sigo como estava fazendo com meus Mbs (como aprendi na
JavaMagazine):

applicationContext.xml:

<beans ...>
<bean id="entityManagerFactory"
lass="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="persistenceUnitName" value="TESTE"/>
</bean>

<bean id="transactionManager"
class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="entityManagerFactory"/>
</bean>

<bean class="org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor"/>

<tx:annotation-driven />
<bean id="interessadoDao" class="br.org.emp.dao.InteressadoDAO"/>
<bean id="assuntoDao" class="br.org.emp.dao.AssuntoDAO"/>
<bean id="localizacaoDao" class="br.org.emp.dao.LocalizacaoDAO"/>
</beans>

Listener:

import ...
public class TaskManagerBuscaNet implements Serializable, ServletContextListener
{
Timer timer;
public void contextInitialized(ServletContextEvent sce)
{
timer = new Timer();
//faz os cálculo para agendar a tarefa
timer.scheduleAtFixedRate(new BuscaTRF3(),delay, period);
}
public void contextDestroyed(ServletContextEvent sce)
{
if (timer != null)
{
timer.cancel();
}
}
}

DAO de acesso DB e busca na net:

import ...
@Transactional
public class BuscaNetDAO implements Serializable
{
private EntityManager entityManager;
@PersistenceContext
public void setEntityManager(EntityManager entityManager)
{
this.entityManager = entityManager;
}
protected EntityManager getEntityManager()
{
return (this.entityManager);
}
@Transactional(readOnly = true)
public void processaDB()
{
String query = “SELECT a FROM ...”
List<SuperEntity> consulta =
this.entityManager.createQuery(query).getResultList();
//faz a busca no DB e na net e processa do resultado atualizando o DB
}
}

Ah, devo salientar que o Listener com esta funcionalidade (acesso ao
BD, busca na internet e atualização do BD) está funcionando sem
problema via JDBC.

E ai, conseguir ver oq tô fazendo de errado?

Muito obrigado novamente.
[]'s
t++
t++

2011/8/5 Bruno Maomeh <bruno...@gmail.com>:

Bruno Maomeh

unread,
Aug 8, 2011, 11:14:28 AM8/8/11
to jav...@googlegroups.com
e quando você chama esse método ae no teu dao?

Charles

unread,
Aug 8, 2011, 12:00:44 PM8/8/11
to jav...@googlegroups.com
foi malz Bruno, acabei apagando comentários errados q era d um outro
código d consulta aq ai ficou + confuso.

meu DAO estende a classe TimerTask e no run dele chamo o método que
deveria fazer o acesso ao BD mas meu entityManager vem sempre como
null.
ñ sei pq ele ñ é instaciado pelo Spring sendo q ele tá anotado e tem a
delegação no applicationContex.

já coloquei o acesso ao DB em outro bean e fiz a injeção pelo
applicationContext mas ñ tá rolando.

E ai, alguma luz?

Segue os fragmentos:

Muito obrigado.

Listener

import ...
public class TaskManagerBuscaNet implements Serializable,
ServletContextListener
{
Timer timer;
public void contextInitialized(ServletContextEvent sce)
{
timer = new Timer();

//faz os cálculo para agenda, o delay e o period
timer.scheduleAtFixedRate(new BuscaNetDAO(), delay, period);


}
public void contextDestroyed(ServletContextEvent sce)
{
if (timer != null)
{
timer.cancel();
}
}
}

BuscanetDAO.java

import ...
@Transactional
public class BuscaNetDAO extends TimerTask implements Serializable
{
private EntityManager entityManager;

@PersistenceContext
public void setEntityManager(EntityManager entityManager)
{
this.entityManager = entityManager;
}

protected EntityManager getEntityManager()
{
return (this.entityManager);
}

@Transactional(readOnly = true)
private void processaDB()


{
String query = “SELECT a FROM ...”
List<SuperEntity>
consulta=this.entityManager.createQuery(query).getResultList();

//à partir daqui deveria fazer a busca no DB mas não faz pois o
entityManager é null
}

@Override
public void run()
{
//faz a busca no DB, na net e processa do resultado atualizando o DB
processaDB();
}
}

2011/8/8 Bruno Maomeh <bruno...@gmail.com>:

Bruno Maomeh

unread,
Aug 8, 2011, 12:31:58 PM8/8/11
to jav...@googlegroups.com
timer.scheduleAtFixedRate(new BuscaNetDAO(), delay, period);

tu tá criando uma nova instancia do teu BuscaNetDAO.. e não usando uma instancia gerenciada pelo spring..
o spring não conhece essa instancia.. por isso não consegue injetar nada nela..

Charles

unread,
Aug 8, 2011, 2:08:43 PM8/8/11
to jav...@googlegroups.com
Eita...

Bruno, num contexto deste, qual é a melhor solução? como vc faria?

Muito obrigado pela ajuda.
[]'s

2011/8/8 Bruno Maomeh <bruno...@gmail.com>:

Bruno Maomeh

unread,
Aug 8, 2011, 2:26:31 PM8/8/11
to jav...@googlegroups.com
utilizaria um scheduler.. como o ponte falou, usaria o scheduler próprio de spring 3x..
caso tiver uma mais antiga do spring.. iria com o quartz..

Charles

unread,
Aug 8, 2011, 3:19:56 PM8/8/11
to jav...@googlegroups.com
Gostei muito da configuração do Quartz via .xml, achei mais simples e
clara. Provavelmente deve ser pq ñ tenho a experiência q vcs.

Como estou usando o Spring 3.x vou estudar um pouco mais o "scheduler"
para tentar manter td sobre o msm "guarda-chuva".

Vou tentar usar IoC aq mas creio q preciso aprofundar meus conceitos
pois acertei oq vc tinha me apontado como errado, segui a "cartilha" e
ñ deu certo.

Muito obrigado msm pela ajuda Bruno!
[]'s
t++

2011/8/8 Bruno Maomeh <bruno...@gmail.com>:

Reply all
Reply to author
Forward
0 new messages