Précédent   Forum des professionnels en informatique > Java > Général Java > Spring
Spring Forum d'entraide pour le framework Spring. Avant de poster -> FAQ Spring
Partagez cette discussion sur d'autres réseaux sociaux : Viadeo Twitter Google Facebook Digg Delicious MySpace Yahoo
Réponse Proposer ce sujet en actualité
 
Outils de la discussion
Publicité
'
Vieux 15/01/2012, 18h36   #1
Membre régulier
 
Christophe
Inscription : novembre 2009
Messages : 78
Détails du profil
Informations personnelles :
Nom : Christophe

Informations forums :
Inscription : novembre 2009
Messages : 78
Points : 73
Points : 73
Par défaut Remplacer Singleton de connexion à la bdd

Bonjour,

j'ai un devoir qui consiste, entre autres, à passer d'un singleton basique (connexion JDBC) à l'utilisation de Spring.
En bref, je dois virer le singleton de mon projet et utiliser l'injection de dépendances.
Mais j'ai quelques problèmes pour le faire...

Actuellement, j'ai un singleton qui instancie un objet de type Connection :
Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
 
public class ConnectionManager
{
        private Connection connect;
 	private static final Logger log = LoggerFactory.getLogger(ConnectionManager.class);
 
	public static Connection getInstance()
	{
		if (connect == null) {
			try {
				connect = DriverManager.getConnection("jdbc:mysql://localhost:3306/projetspring", "root", "password");
			}
			catch (SQLException e) {
				log.debug("Connection failed ! ", e);
			}
		}
 
		return connect;
	}
}
Pour réaliser mon travail et remplacer ce fameux singleton, j'ai donc essayé avec Spring ceci dans mon applicationContext.xml :

Code :
1
2
3
4
5
6
7
8
9
10
11
12
	<bean id="propertyConfigurer"
		class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
		<property name="location" value="classpath:database.properties" />
	</bean>
 
	<bean id="dataSource"
		class="org.springframework.jdbc.datasource.DriverManagerDataSource">
		<property name="driverClassName" value="${jdbc.driverClassName}" />
		<property name="url" value="${jdbc.url}" />
		<property name="username" value="${jdbc.username}" />
		<property name="password" value="${jdbc.password}" />
	</bean>
Mon database.properties:

Code :
1
2
3
4
jdbc.driverClassName=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/projetspring
jdbc.username=root
jdbc.password=password
Mais là, je tombe sur un problème. Premièrement, mon code dans Spring instancie un objet de type "DriverManagerDataSource". Or, j'aimerai obtenir un objet de type Connection !

Du coup, j'ai tenté dans mon DAO :
Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
public class UserDao {
	private final static Logger log = LoggerFactory.getLogger(MediaDao.class);
	@Resource DriverManagerDataSource dataSource;
	Connection conn;
	
	public UserDao()
	{
		try {
			this.conn = this.dataSource.getConnection();
		}
		catch (SQLException e) {
			e.printStackTrace();
		}
	}
}
Mais ça ne fonctionne pas. L'objet retourné est NULL.
Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
 
 
Caused by: org.springframework.beans.BeanInstantiationException: Could not instantiate bean class [fr.gesa.opr.user.dao.UserDao]: Constructor threw exception; nested exception is java.lang.NullPointerException
	at org.springframework.beans.BeanUtils.instantiateClass(BeanUtils.java:162)
	at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:76)
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateBean(AbstractAutowireCapableBeanFactory.java:990)
	... 43 more
Caused by: java.lang.NullPointerException
	at fr.gesa.opr.user.dao.UserDao.<init>(UserDao.java:35)
	at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
	at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:57)
	at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
	at java.lang.reflect.Constructor.newInstance(Constructor.java:532)
	at org.springframework.beans.BeanUtils.instantiateClass(BeanUtils.java:147)
	... 45 more

Ma question est donc la suivante : Comment puis-je récupérer un objet de type Connection avec Spring afin de l'injecter dans ma classe DAO ?

Je vous remercie
chewing-gum est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 15/01/2012, 19h07   #2
Modérateur
 
Avatar de tchize_
 
Homme
Responsable de service informatique
Inscription : avril 2007
Messages : 16 196
Détails du profil
Informations personnelles :
Sexe : Homme
Âge : 32
Localisation : Belgique

Informations professionnelles :
Activité : Responsable de service informatique
Secteur : Service public

Informations forums :
Inscription : avril 2007
Messages : 16 196
Points : 25 344
Points : 25 344
Envoyer un message via MSN à tchize_ Envoyer un message via Skype™ à tchize_
C'est ton datasource qui est null. Il est null parce que spring ne l'a pas encore injecté. Spring ne l'a pas encore injecté parce qu'il est seulement à l'étape de construction de ton objet.

Tu ne dois utiliser dans ton constructeur aucun champ injecté par spring
__________________
⥀⥁ Чиз faq java, cours java, javadoc. Pensez à et
"Votre génitrice tute des pédoncules au pandémonium" (le conjurateur, 1973)
tchize_ est déconnecté   Envoyer un message privé Réponse avec citation 20
Vieux 15/01/2012, 20h11   #3
Membre régulier
 
Christophe
Inscription : novembre 2009
Messages : 78
Détails du profil
Informations personnelles :
Nom : Christophe

Informations forums :
Inscription : novembre 2009
Messages : 78
Points : 73
Points : 73
Merci pour la réponse rapide.

Dans ce cas là, je ne vois pas où je pourrais récupérer mon objet de type Connection si ce n'est pas dans le constructeur.
Soit je le fais au début de chaque méthode que j'utilise dans mon DAO (c'est répétitif), soit je trouve une autre solution.
Et à vrai dire, je n'ai pas d'idées car je débute avec Spring.

Auriez-vous une idée pour que je puisse injecter simplement mon objet Connection ? Ou même un lien vers une doc qui ressemble à peu près à ce que je veux faire ?

Je vous remercie
chewing-gum est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 15/01/2012, 21h33   #4
Modérateur
 
Avatar de tchize_
 
Homme
Responsable de service informatique
Inscription : avril 2007
Messages : 16 196
Détails du profil
Informations personnelles :
Sexe : Homme
Âge : 32
Localisation : Belgique

Informations professionnelles :
Activité : Responsable de service informatique
Secteur : Service public

Informations forums :
Inscription : avril 2007
Messages : 16 196
Points : 25 344
Points : 25 344
Envoyer un message via MSN à tchize_ Envoyer un message via Skype™ à tchize_
A priori, c'est à chaque appel au DAO qu'on effectue une demande de connexion au datasource, ça permet de gérer correctement le multi tâches et ça évite aussi de maintenir trop longtemps un connexion.

Au delà de ça, pour votre initialisation, vous avez deux possibilités pratiques:

Soit créer une méthode "init" (ou autre nom) dans votre dao qui fait ce travail et demander à spring d'appeler cette méthode (paramètre init-method du tag <bean>)

Soit passer en paramètre au constructeur les objets dont vous avez besoin dans le constructeur (<contructor-arg> dans le fichier spring)
__________________
⥀⥁ Чиз faq java, cours java, javadoc. Pensez à et
"Votre génitrice tute des pédoncules au pandémonium" (le conjurateur, 1973)
tchize_ est déconnecté   Envoyer un message privé Réponse avec citation 10
Vieux 16/01/2012, 00h03   #5
Membre régulier
 
Christophe
Inscription : novembre 2009
Messages : 78
Détails du profil
Informations personnelles :
Nom : Christophe

Informations forums :
Inscription : novembre 2009
Messages : 78
Points : 73
Points : 73
Encore merci pour cette réponse.

J'ai finalement réussi ce que je voulais grâce à votre aide.
J'ai ajouté une méthode init() à ma classe DAO. Puis, j'ai appelé avec spring cette méthode comme vous me l'avez indiqué (et en regardant la doc pour la syntaxe) pour modifier ma variable de connexion.

Résolu
chewing-gum est déconnecté   Envoyer un message privé Réponse avec citation 00
Réponse Proposer ce sujet en actualité Cette discussion est résolue.
Outils de la discussion



Fuseau horaire GMT +2. Il est actuellement 23h43.


 
 
 
 
Partenaires

Hébergement Web