Bonjour,

je suis confronté à un soucis dans mes tests que je ne comprend pas. Je test ma couche de DAO, et j'ai l'exception suivante de levée (en résumé) :

Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
 
javax.ejb.EJBException: java.lang.IllegalArgumentException: Removing a detached instance org.javacrea.gestioncontacts.pu.Contact#1
                    at org.javacrea.test.gestioncontacts.TestDAO.createContact(TestDAO.java:91)
Caused by: java.lang.IllegalArgumentException: Removing a detached instance org.javacrea.gestioncontacts.pu.Contact#1
Le code du test est le suivant :

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
@RunWith(Arquillian.class)
public class TestDAO {
 
	@Inject
	private GestionContacts fichier;
 
	@Deployment
	public static Archive<?> createDeployment() {
		return ShrinkWrap
				.create(JavaArchive.class, "DAOTest.jar")
				.addClasses(GestionContacts.class, GestionContactsLocal.class, GestionContactsRemote.class, GestionContactsImpl.class, NullCriteriaValueException.class, MissingCVLineDatesException.class)
				.addPackage(Contact.class.getPackage())
				.addAsManifestResource("META-INF/test-beans.xml", "beans.xml")
				.addAsResource("META-INF/test-persist.xml","META-INF/persistence.xml");
	}
 
 
	public void injectFichier(){
		Assert.assertNotNull(fichier);
		Assert.assertEquals("OK", fichier.test());
	}
 
 
	public void vider(){
		fichier.closeSession();
		List<Contact> all = fichier.chargerFichier();
		for(Contact c : all){
			fichier.updateContact(c);
			fichier.deleteContact(c);
		}
		fichier.saveSession();
	}
 
 
	public void createContact() throws ParseException, MissingCVLineDatesException{
		Contact moi = fichier.createContact("Monsieur","Delalleau", "François");
		Assert.assertNotNull(moi);
		Assert.assertTrue(moi.getId()!=null);
		int i = moi.getId();
		moi.addAdressePerso(new Adresse("mon adresse", "92110", "Clichy", null));
		moi.addEmail(new Email("f.delalleau@gmail.com"));
		moi.addTelephone(new LigneDirecte("0686000000"));
		boolean saved = fichier.updateContact(moi);
		Assert.assertTrue(saved);
		moi = fichier.trouverContact("Delalleau").get(0);
		Assert.assertEquals("François", moi.getPrenom());
		fichier.closeSession();
		Assert.assertNotNull(fichier.readContact(i));
		moi = fichier.readContact(i);
		boolean	persistent = fichier.updateContact(moi);
		Assert.assertTrue(persistent);
		fichier.deleteContact(moi);                         // => l'erreur est ici
		Assert.assertNull(fichier.readContact(i));
		System.out.println("CRUD contact OK!");
		fichier.closeSession();
	}
 
	@Test
	public void runTest() throws ParseException, MissingCVLineDatesException{
		injectFichier();
		vider();
		createContact();
		vider();
	}
}
Et la classe de DAO (je zappe les méthodes non employées dans ce test):

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
@Singleton
@ApplicationScoped
@TransactionAttribute(TransactionAttributeType.REQUIRED)
public class GestionContactsImpl implements GestionContactsLocal,
		GestionContactsRemote {
 
	private Integer dirtyCount = 0;
 
	@PersistenceContext(unitName = "GestionContacts")
	private Session session;
 
	@PostConstruct
	public void checkFlush() {
		session.setFlushMode(FlushMode.COMMIT);
	}
 
	public String test() {
		return "OK";
	}
 
	@SuppressWarnings("unchecked")
	public List<Contact> chargerFichier() {
		isTooDirty();
		return session.createQuery("select c from Contact c").list();
	}
 
	@SuppressWarnings("unchecked")
	public List<Contact> trouverContact(String nom) {
		isTooDirty();
		return session
				.createQuery("select c from Contact c where c.nom like :nom")
				.setParameter("nom", nom).list();
	}
 
	...
 
	@Override
	public Contact createContact(String titre, String nom, String prenom) {
		Contact contact = new Contact();
		contact.setTitre(titre);
		contact.setNom(nom);
		contact.setPrenom(prenom);
		session.save(contact);
		isTooDirty();
		return contact;
	}
 
	@Override
	public Contact readContact(Integer id) {
		isTooDirty();
		Contact c = (Contact) session.get(Contact.class, id);
		if(c!=null){
		return c;
		} else {
			throw new EntityNotFoundException();
		}
	}
 
	@Override
	public boolean updateContact(Contact contact) {
		session.saveOrUpdate(contact);
		isTooDirty();
		return session.contains(contact);
	}
 
	@Override
	public boolean deleteContact(Contact contact) {
		session.delete(contact);
		isTooDirty();
		return !session.contains(contact);
	}
 
	@Override
	public void saveSession() {
		session.flush();
	}
 
	@Override
	public void closeSession() {
		session.flush();
		session.clear();
	}
 
	private void isTooDirty() {
		if(session.isDirty()){
			dirtyCount++;
		}
		if(dirtyCount>10){
			saveSession();
		}
	}
J'ai probablement mal compris quelque chose dans l'utilisation de Hibernate, si quelqu'un peut m'éclairer.