Problème d'injection de DAO avec Spring
Bonjour,
Je suis débutant sur le Framework Spring et je fais appel à vous car cela fait quelques jours que je suis bloqué sur ce problème malgré mes recherches sur le web.
Ce problème apparais dans plusieurs forums techniques, mais je n'ai pas trouvé de solution, ni d'explication claire répondant à mon besoin. (les solutions proposées ne fonctionnant pas pour moi, j'en déduis que soit elle ne correspond pas à mon problème, soit je n'ai rien compris à la configuration de Spring, voir les deux).
Mon objectif est de faire fonctionner un petit serveur de test pour comprendre le fonctionnement des web services avec les outils Tomcat + Spring + Hibernate + JPA + CXF.
La partie DAO fonctionne correctement, un test côté serveur avec JUnit passe sans souci.
voici le code côté serveur :
ApplicationContext.xml (j'ai intégré la parti accès au données dans ce fichier de conf, mais il est en principe dans un autre fichier)
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
|
<!-- Chargement modules CXF. -->
<import resource="classpath:META-INF/cxf/cxf.xml" />
<import resource="classpath:META-INF/cxf/cxf-extension-soap.xml" />
<import resource="classpath:META-INF/cxf/cxf-servlet.xml" />
<context:component-scan base-package="com.test" />
<context:annotation-config />
<!-- Couches applicatives. -->
<bean id="paysDao" class="com.test.dao.PaysDao"/>
<bean id="paysWS" class="com.test.ws.PaysWS">
<property name="paysDao" ref="paysDao" />
</bean>
<!-- Définition du Endpoint JAX-WS.-->
<jaxws:endpoint id="paysService"
implementor="com.test.ws.PaysWS"
address="/PaysService">
</jaxws:endpoint> |
IPaysWS.java
Code:
1 2 3 4 5 6 7 8 9 10 11
|
@WebService
public interface IPaysWS {
@WebMethod
public String getFrance() throws WebServiceException;
@WebMethod
public List<Pays> findPaysAll() throws WebServiceException;
} |
PaysWS.java
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
|
public class PaysWS implements IPaysWS, Serializable {
private static final long serialVersionUID = 1L;
@Autowired
IPaysDao paysDao;
public void setPaysDao( IPaysDao paysDao ) {
this.paysDao = paysDao;
}
public String getFrance() {
return "France";
}
public List<Pays> findPaysAll() {
return paysDao.findAll();
}
} |
IPaysDao.java
Code:
1 2 3 4 5 6
|
public interface IPaysDao {
public List<Pays> findAll();
} |
PaysDao.java
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
|
@Transactional
public class PaysDao implements IPaysDao, Serializable {
private static final long serialVersionUID = 1L;
private static final String SQL_SELECT = "from Pays";
@PersistenceContext
private EntityManager entityManager;
public void setEntityManager( EntityManager entityManager ) {
this.entityManager = entityManager;
}
@SuppressWarnings( "unchecked" )
public List<Pays> findAll() {
try {
return entityManager.createQuery( SQL_SELECT ).getResultList();
} catch ( Throwable th ) {
throw new ExceptionJPA( th, 1 );
}
}
} |
coté client :
client-beans.xml
Code:
1 2 3 4
|
<jaxws:client id="paysWS" serviceClass="com.test.ws.IPaysWS"
address="http://10.101.110.54:8080/TestSpringWebService/PaysService">
</jaxws:client> |
client.java
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
|
public static void main( String args[] ) throws Exception {
ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext( "client-beans.xml" );
IPaysWS paysService = (IPaysWS) ctx.getBean( "paysWS" );
if ( paysService != null ) {
System.out.println( paysService.getFrance() );
List<Pays> listPays = new ArrayList<Pays>();
listPays = paysService.findPaysAll();
for ( Pays pays : listPays ) {
System.out.println( pays.getNom() );
}
}
} |
J'utilise les pays par habitude durant mes essais, ça change des beans habituelles, mais là n'est pas le problème.
Quand je fais appel aux web services avec mon client, la méthode getFrance() me retourne bien "France", en revanche que j'utilise la méthode findPaysAll(), paysDao est à null et Tomcat me renvoi donc un jolie NullPointerException
j'ai bien trouvé une solution en créant une Factory à la main pour injecter la Dao dans paysWS avec :
Code:
1 2 3 4
|
public IPaysDao getPaysDao() {
return DAOFactory.getInstance().getPaysDao();
} |
mais cela ne me convient pas, je pense que Spring doit pouvoir le faire.
Il me semble que j'ai pourtant bien respecté la doc
j'ai 2 hypothèses :
- La DAO n'est plus instanciée au moment où je fais appel à elle, pourtant quand je fais le test avec JUnit cela fonctionne.
- Spring ne fait pas l'injection de paysDao dans paysWS et donc paysWS ne peut pas répondre quand j'attaque la DAO, là ça voudrais dire que je n’ai pas compris comment faire.
Quelqu'un aurait-il une idée du problème ou un début d'explication ?
Merci de votre attention.