Bonjour à tous !

Je suis nouveau sur le forum et je développe pour la toute première fois un back office en J2EE.
Je viens vers vous pour essayer de trouver une solution à mon problème. Je vais essayer de vous donner un maximum de renseignement pour bien immerger les personnes susceptibles de m'aider dans mon problème. Si il vous manquait des informations, n'hésitez pas à me les demander.

J'utilise pour ce projet la plateforme de développement suivante :
OS : Ubuntu 9.04
EDI : Netbeans 6.5
BDD : MySQL 5.0.75
Serveur d'application : Glassfish v2 (celui de NetBeans pour le moment)

Explication du problème :
J'utilise la persistence via TopLinkEssantial.
J'injecte mon entity manager manuellement via le nom de l'unité de persistence (aucun soucis de ce côté). L'injection manuelle vient du fait que je dois pouvoir via ce back office me connecter à plusieurs bases de données, donc utiliser plusieurs unité de persistence.
Pour le moment, une seule est utilisé pour le développement (dans le fichier de persistence.xml un peu plus bas).
Je peux parfaitement faire entityManager.find(...), entityManager.createNamedQuery(...).getListResult();
Je peux également faire entityManager.persist(), entityManager.remove() et entityManager.update() mais cela n'a malheureusement aucun effet sur ma base de données.

Peut-être me suis-je trompé quelque part (certainement même )

Quelque qu'un aura peut-être une solution à mon problème ? N'hésitez pas à demandez ce qu'il vous manque, je répondrais rapidement.

Maintenant, place à quelques fichiers de mon projet pour vous aidez à ... m'aidez !!!


Le fichier de persistence utilise un pool de connexion de Glassfish d'où le noeud <jta-data-source>.

Persistence.xml :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
 
<?xml version="1.0" encoding="UTF-8"?>
<persistence version="1.0" xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd">
	<persistence-unit name="XDMS" transaction-type="JTA">
		<provider>oracle.toplink.essentials.PersistenceProvider</provider>
		<jta-data-source>jdbc/XDMS</jta-data-source>
		...
		<class>com.acnet.xdms.entity.City</class>
		...
		<properties>
		</properties>
	</persistence-unit>
</persistence>
AbstractEntity définit simplement l'ID des enregistrements pour toutes les autres entités qui héritent obligatoirement de cette class abstraite.

AbstractEntity.java :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
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
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
 
package com.acnet.xdms.entity;
 
import javax.persistence.Column;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.MappedSuperclass;
 
/**
 * Classe d'abstraction d'un enregistrement
 *
 * @author t4zloune
 */
@MappedSuperclass
abstract public class AbstractEntity {
 
	/**
         * Identifiant de l'enregistrement
         */
	@Id
	@GeneratedValue(strategy = GenerationType.AUTO)
	@Column(name = "id", nullable = false, unique = true)
	private Integer id;
 
	/**
         * Construire un nouveau AbstractEntity
         */
	protected AbstractEntity() {
		this(null);
	}
 
	/**
         * Construire un nouveau AbstractEntity
         *
         * @param id L'identifiant de l'enregistrement.
         */
	protected AbstractEntity(Integer id) {
		super();
		this.id = id;
	}
 
	/**
         * Déterminer si un objet est égal à celui-ci
         *
         * @param object L'objet à déterminer.
         * @return Retourne true en cas d'égalité, false sinon.
         */
	@Override
	public boolean equals(Object object) {
		...
	}
 
	/**
         * Obtenir l'identifiant de l'enregistrement
         *
         * @return Retourne l'identifiant de l'enregistrement.
         */
	public Integer getId() {
		return (this.id);
	}
 
	/**
         * Retourner un code de hashage
         *
         * @return Retourne un code de hashage.
         */
	@Override
	public int hashCode() {
		...
	}
 
	/**
         * Initialiser l'identifiant de l'enregistrement
         *
         * @param id L'identifiant de l'enregistrement.
         */
	public void setId(Integer id) {
		this.id = id;
	}
 
	/**
         * Convertir l'objet sous forme de chaîne de caractères
         *
         * @return Retourne une chaîne de caractères représentant cet objet.
         */
	@Override
	public String toString() {
		...
	}
}
City, une entité que j'ai pioché parmi toutes celles présentes dans mon application. Elle hérite d'AbstractEntity comme expliqué plus haut dans ce post.

City.java :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
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
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
 
package com.acnet.xdms.entity;
 
import java.io.Serializable;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.JoinColumn;
import javax.persistence.NamedQueries;
import javax.persistence.NamedQuery;
import javax.persistence.OneToOne;
import javax.persistence.Table;
 
/**
 * Classe représentative d'un enregistrement Ville
 *
 * @author t4zloune
 */
@Entity
@NamedQueries({
	@NamedQuery(name = "City.countAll", query = "SELECT COUNT(e) FROM City e"),
	@NamedQuery(name = "City.listAll", query = "SELECT e FROM City e ORDER BY e.id ASC"),
	@NamedQuery(name = "City.listByDepartment", query = "SELECT e FROM City e WHERE e.department = :value0 ORDER BY e.id ASC")
})
@Table(name = "cities")
public class City extends AbstractEntity implements Serializable {
 
	private static final long serialVersionUID = 1L;
	/**
         * Département de la ville
         */
	@OneToOne
	@JoinColumn(name = "department_fk", nullable = false)
	private Department department;
	/**
         * Nom de la ville
         */
	@Column(name = "name", nullable = false, length = 32)
	private String name;
	/**
         * Code postal de la ville
         */
	@Column(name = "zip_code", length = 5, nullable = false)
	private String zipCode;
 
	/**
         * Construire un nouveau City
         */
	public City() {
		this(null);
	}
 
	/**
         * Construire un nouveau City
         *
         * @param id L'identifiant de la ville.
         */
	public City(Integer id) {
		this(id, null, null, null);
	}
 
	/**
         * Construire un nouveau City
         * 
         * @param id L'identifiant de la ville.
         * @param name Le nom de la ville.
         * @param zipCode Le code postal de la ville.
         * @param department Le département de la ville.
         */
	public City(Integer id, String name, String zipCode, Department department) {
		super(id);
		this.department = department;
		this.name = name;
		this.zipCode = zipCode;
	}
 
	/**
         * Getters & Setters
         */
	...
 
	/**
         * Convertir l'objet sous forme de chaîne de caractères
         *
         * @return Retourne une chaîne de caractères représentant cet objet.
         */
	@Override
	public String toString() {
		...
	}
}
AbstractManager définit simplement les méthodes communes pour la gestion des entités.

AbstractManager.java :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
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
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
 
package com.acnet.xdms.manager;
 
import com.acnet.xdms.entity.AbstractEntity;
import java.util.List;
import javax.persistence.EntityManager;
import javax.persistence.Persistence;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;
 
/**
 * Classe d'abstraction de gestion des enregistrements
 *
 * @author T4zloune
 */
abstract public class AbstractManager {
 
	/**
         * Gestionnaire des enregistrements
         */
	@PersistenceContext
	private EntityManager entityManager;
	/**
         * Autres attributs
         */
	...
 
	/**
         * Construire un nouveau AbstractManager
         */
	protected AbstractManager() {
		this("XDMS");
	}
 
	/**
         * Construire un nouveau AbstractManager
         *
         * @param persistenceUnit Le nom de l'unité de persistence
         */
	protected AbstractManager(String persistenceUnit) {
		super();
		this.entityManager = Persistence.createEntityManagerFactory(persistenceUnit).createEntityManager();
		...
	}
 
	/**
         * Quelques méthodes sans importance pour mon problème
         */
	...
 
	/**
         * Compter les enregistrements
         *
         * @return Retourne le nombre d'enregistrements.
         */
	abstract public int count();
 
	/**
         * Compter les enregistrements
         *
         * @param countQueryName Le nom de la requète JPQL pour compter les enregistrements.
         * @return Retourne le nombre d'enregistrements, -1 sinon.
         */
	protected int countRecords(String countQueryName) {
		if ((countQueryName != null) && (this.entityManager != null)) {
			Query query = this.entityManager.createNamedQuery(countQueryName); // Initialiser la requète.
			Long countModel = (Long) query.getSingleResult(); // Exécuter la requète et obtenir le résultat.
			return (countModel.intValue()); // Retourner le nombre d'enregistrements.
		} // if
		return (-1);
	}
 
	/**
         * Créer un enregistrement
         *
         * @param entity L'enregistrement à créer.
         * @return Retourne true en cas de succès, false sinon.
         */
	protected boolean createRecord(AbstractEntity entity) {
		if ((entity != null) && (this.entityManager != null)) {
			this.entityManager.persist(this.entityManager.merge(entity)); // Créer l'enregistrement.
			return (true);
		} // if
		return (false);
	}
 
	/**
         * Supprimer un enregistrement
         *
         * @param entity L'enregistrement à supprimer.
         * @return Retourne true en cas de succès, false sinon.
         */
	protected boolean deleteRecord(AbstractEntity entity) {
		if ((entity != null) && (this.entityManager != null)) {
			this.entityManager.remove(this.entityManager.merge(entity)); // Supprimer l'enregistrement.
			return (true);
		} // if
		return (false);
	}
 
	/**
         * Obtenir le gestionnaire des enregistrements
         *
         * @return Retourne le gestionnaire des enregistrements.
         */
	protected EntityManager getEntityManager() {
		return (this.entityManager);
	}
 
	/**
        /**
         * Lister les enregistrements
         *
         * @param listQueryName Le nom de la requète JPQL pour lister les enregistrements.
         * @param listQueryValues Les valeurs pour lister.
         * @param recordIndex L'index du premier enregistrement à lister.
         * @param recordsNumber Le nombre d'enregistrement à lister.
         * @return Retourne la liste des enregistrements, null sinon.
         */
	private List listRecords(String listQueryName, Object[] listQueryValues, int recordIndex, int recordsNumber) {
		if ((listQueryName != null) && (0 <= recordIndex) && (0 < recordsNumber)) {
			Query query = this.entityManager.createNamedQuery(listQueryName);
			if (listQueryValues != null) {
				this.preformatQuery(query, listQueryValues);
			} // if
			query.setFirstResult(recordIndex);
			query.setMaxResults(recordsNumber);
			return (query.getResultList());
		} // if
		return (null);
	}
 
	/**
         * Lister les enregistrements
         *
         * @param listQueryName Le nom de la requète JPQL pour lister les enregistrements.
         * @return Retourne la liste des enregistrements
         */
	protected List listRecords(String listQueryName) {
		return (this.listRecords(listQueryName, null, 0, this.getRecordsNumber()));
	}
 
	/**
         * Lister les enregistrements d'une page
         *
         * @param listQueryName Le nom de la requète JPQL pour lister les enregistrements d'un page.
         * @param aPageNumber Le numéro de page.
         * @return Retourne la liste d'enregistrements d'une page, null sinon.
         */
	protected List listRecords(String listQueryName, int aPageNumber) {
		return (this.listRecords(listQueryName, null, this.recordsNumberPerPage * (this.checkPageNumber(aPageNumber) - 1), this.recordsNumberPerPage));
	}
 
	/**
         * Lister les enregistrements d'une page
         *
         * @param listQueryName Le nom de la requète JPQL pour lister les enregistrements d'un page.
         * @param aPageNumber Le numéro de page.
         * @return Retourne la liste d'enregistrements d'une page, null sinon.
         */
	protected List listRecords(String listQueryName, String aPageNumber) {
		return (this.listRecords(listQueryName, this.stringToInt(aPageNumber)));
	}
 
	/**
         * Préformater une requète JPQL
         *
         * @param query La requète JPQL à préformater.
         * @param values Les paramètres pour préformater.
         * @return Retourne la requète JPQL préformatée.
         */
	private Query preformatQuery(Query query, Object[] values) {
		if ((query != null) && (values != null) && (this.entityManager != null)) {
			// Pour chaque valeur.
			for (int i = 0; i < values.length; i++) {
				query.setParameter("value" + i, values[i]);
			} // if
		} // if
		// Retourner la requète préformatée.
		return (query);
	}
 
	/**
         * Lire un enregistrement
         *
         * @param entity L'enregistrement à lire.
         * @return Retourne l'enregistrement lu, null sinon.
         */
	protected AbstractEntity readRecord(AbstractEntity entity) {
		if ((entity != null) && (this.entityManager != null)) {
			return (this.entityManager.find(entity.getClass(), entity.getId()));
		} // if
		return (null);
	}
 
	/**
         * Rechercher des enregistrements
         *
         * @param searchQueryName La requète JPQL pour rechercher des enregistrements.
         * @param searchQueryValues Les valeurs de la requètes JPQL pour rechercher des enregistrements.
         * @return Retourne la liste des enregistrements, null sinon.
         */
	protected List searchRecords(String searchQueryName, Object[] searchQueryValues) {
		return (this.listRecords(searchQueryName, searchQueryValues, 0, this.getRecordsNumber()));
	}
 
	/**
         * Initialiser le gestionnaire des enregistrements
         *
         * @param entityManager Le gestionnaire des enregistrements.
         */
	private void setEntityManager(EntityManager entityManager) {
		this.entityManager = entityManager;
	}
 
	/**
         * Convertir une chaîne de caractères en entier
         *
         * @param aString La chaîne de carcatères à convertir.
         * @return Retourne la conversion de la chaîne de carcatères.
         */
	private int stringToInt(String aString) {
		Integer anInteger = null;
		try {
			anInteger = new Integer(aString);
		} catch (NumberFormatException numberFormatException) {
			anInteger = new Integer(1);
		} // try
		return (anInteger.intValue());
	}
 
	/**
         * Mettre à jour un enregistrement
         *
         * @param entity L'enregistrement à mettre à jour.
         * @return Retourne true en cas de succès, false sinon.
         */
	protected boolean updateRecord(AbstractEntity entity) {
		if ((entity != null) && (this.entityManager != null)) {
			this.entityManager.merge(entity); // Mettre à jour l'enregistrement.
			return (true);
		} // if
		return (false);
	}
}
CityManager s'occupe de gérer les entités de type City avec les méthodes héritées d'AbstractManager.
Il y'a donc un manager par type d'entité permettant de faire des choses simples.
Peut-être n'est ce pas la bonne méthode mais pour le moment, elle fonctionne trés bien pour mon besoin.

CityManager.java :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
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
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
 
package com.acnet.xdms.manager;
 
import com.acnet.xdms.entity.City;
import com.acnet.xdms.entity.Department;
import java.util.List;
 
/**
 * Classe de gestion des enregistrements
 *
 * @author T4zloune
 */
public class CityManager extends AbstractManager {
 
	/**
         * Construire un nouveau CityManager
         */
	public CityManager() {
		super();
	}
 
	/**
         * Construire un nouveau CityManager
         *
         * @param persistenceUnitName Le nom de l'unité de persistence.
         */
	public CityManager(String persistenceUnitName) {
		super(persistenceUnitName);
	}
 
	/**
         * Compter les enregistrements
         *
         * @return Retourne le nombre d'enregistrements.
         */
	@Override
	public int count() {
		return (super.countRecords("City.countAll"));
	}
 
	/**
         * Créer un enregistrement
         *
         * @param newCity L'enregistrement à créer.
         * @return Retourne true en cas de succès, false sinon.
         */
	public boolean create(City newCity) {
		return (super.createRecord(newCity));
	}
 
 
	/**
         * Lister les enregistrements
         *
         * @return Retourne la liste d'enregistrements, null sinon.
         */
	@SuppressWarnings(value = "unchecked")
	public List<City> list() {
		return ((List<City>) super.listRecords("City.listAll"));
	}
 
	/**
         * Lister les enregistrements d'un département
         *
         * @param department Le département à lister.
         * @return Retourne la liste d'enregistrements d'un département, null sinon.
         */
	@SuppressWarnings(value = "unchecked")
	public List<City> list(Department department) {
		if (department != null) {
			return ((List<City>) super.searchRecords("City.listByDepartment", new Object[]{department}));
		} // if
		return (null);
	}
 
	/**
         * Lister les enregistrements d'une page
         *
         * @param aPageNumber Le numéro de page.
         * @return Retourne la liste d'enregistrements d'une page, null sinon.
         */
	@SuppressWarnings(value = "unchecked")
	public List<City> list(int aPageNumber) {
		return ((List<City>) super.listRecords("City.listAll", aPageNumber));
	}
 
	/**
         * Lister les enregistrements d'une page
         *
         * @param aPageNumber Le numéro de page.
         * @return Retourne la liste d'enregistrements d'une page, null sinon.
         */
	@SuppressWarnings(value = "unchecked")
	public List<City> list(String aPageNumber) {
		return ((List<City>) super.listRecords("City.listAll", aPageNumber));
	}
}
Merci d'avance à ceux qui se pencheront sur mon soucis.

Cordialement, T@zloune