bonjour,

avant tout, je précise que je résume le sujet à la fin du post, et que je dois reconnaître que le début est un peu obscur (ma classe n'est pas très bien écrite).

j'ai un projet java avec : des classes persistantes (entités jpa), des classes DAO faisant des crud dessus,et la méthode de test suivante:

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
 
@Test
    public void test1(){
 
        List<Indemnite> liste=ind.findAll();
        for (Indemnite une_ind : liste){
            System.out.println(une_ind);
        }
 
        System.out.println("--- autre étape ---");
 
        Indemnite deux_ind=new Indemnite(2.1, 1.2, 2, 3);
        ind.create(deux_ind);
 
        System.out.println("--- autre étape ---");
 
        Indemnite indemnite1=ind.findAll().get(0);
        assert (indemnite1.equals(deux_ind));
 
        System.out.println("--- autre étape ---");
 
        indemnite1.setBaseHeure(0.0);
        indemnite1.setEntretienJour(0.0);
        indemnite1.setIndemnitesCp(0.0);
        indemnite1.setRepasJour(0.0);
        Indemnite indemnite2=ind.edit(indemnite1);
 
 
        System.out.println("--- autre étape ---");
 
        System.out.println("indemnite : version = "+deux_ind.getVersion());
        System.out.println("indemnite1 : version = "+indemnite1.getVersion());
        System.out.println("indemnite2 : version = "+indemnite2.getVersion());
 
        System.out.println("--- autre étape ---");
 
        Long id=indemnite2.getIndice();
        //ind.destroy(indemnite2);
 
        System.out.println("--- autre étape ---");
        Indemnite ind3=ind.find(id);
        Long id3=ind3.getIndice();
        ind.destroy(ind3);
 
 
 
        System.out.println("--- autre étape ---");
 
        assert ind.find(id3)==null;
 
 
    }
on suppose que la base est vide au départ.
c'est tiré d'un tuto de Mr TAHE (sur developpez.com, cours jee5 avec netbeans).
les résultats des tests de version sont :
indemnité -> 0
indemnite1-> 0
indemnite2->1

et l'erreur est:

Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
 
erreur dans IndemniteDao - destroy / Removing a detached instance jpa.Indemnite#1
exception.PamException: erreur dans IndemniteDao - destroy / Removing a detached instance jpa.Indemnite#1
        at dao.IndemniteDao.destroy(IndemniteDao.java:78)
        at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:307)
        at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:182)
        at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:149)
        at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:106)
        at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:171)
        at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:204)
        at $Proxy19.destroy(Unknown Source)
        at dao.test_dao.test1(test_dao.java:118)
pour comprendre cette erreur, il faut savoir exactement ce que fait netbeans et l' "API JPA" dans ces différentes lignes.

merci si vous pouvez m'aider,

olivier.

ps: j'oubliais, j'utilise spring et la classe indemniteDao est la suivante:

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
 
@Transactional
public class IndemniteDao implements IIndemniteDao{
 
    EntityManagerFactory emf;
    EntityManager em;
 
    public EntityManagerFactory getEmf() {
        return emf;
    }
 
    public void setEmf(EntityManagerFactory emf) {
        this.emf = emf;
    }
 
 
 
 
    public Indemnite create(Indemnite employe) {
        em=emf.createEntityManager();
        EntityTransaction tx=em.getTransaction();
        try{
            tx.begin();
            em.persist(employe);
            tx.commit();
        }catch (Exception e){
            tx.rollback();
            throw new PamException("erreur dans IndemniteDao - create / "+e.getMessage(), 1);
        }
        return employe;
 
    }
 
    public Indemnite edit(Indemnite employe) {
        em=emf.createEntityManager();
        EntityTransaction tx=em.getTransaction();
        Indemnite employe2=null;
        try{
            tx.begin();
            employe2=em.merge(employe);
            tx.commit();
        }catch (Exception e){
            tx.rollback();
            throw new PamException("erreur dans IndemniteDao - edit / "+e.getMessage(), 1);
        }
        return employe2;
 
    }
 
    public void destroy(Indemnite employe) {
        em=emf.createEntityManager();
        EntityTransaction tx=em.getTransaction();
        try{
            tx.begin();
            em.remove(employe);
            tx.commit();
        }catch (Exception e){
            tx.rollback();
            throw new PamException("erreur dans IndemniteDao - destroy / "+e.getMessage(), 1);
        }
 
 
    }
 
    public Indemnite find(Long id) {
        em=emf.createEntityManager();
        Indemnite employe=em.find(Indemnite.class, id);
        if (employe==null)
            throw new PamException("erreur dans IndemniteDao - find / aucun employe d'id "+id,1);
        return employe;
    }
 
    public List<Indemnite> findAll() {
        em=emf.createEntityManager();
        return em.createQuery("select i from Indemnite i").getResultList();
 
 
 
    }
 
}
ps : j'ai trouvé une réponse mais je ne comprends pas comment ça marche.
l'erreur vient de la classe dao : auparavant (plus haut) j'avais ceci dans ma classe void destroy (Employe employe): un simple em.remove (employe), et cet "employe" je l'avais trouvé grâce à la méthode find de la classe dao juste avant, donc c'était la dernière version en date.
maintenant, j'ai:

Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
 
void destroy(Long id){
     Employe employe=em.find(Employe.getClass(),id);
     em.remove(employe)
}
alors je simplifie:
un DAO.find(id) + un destroy(employe) -> BUG
un destroy(id) qui inclut un em.find(id) -> MARCHE.

je ne comprends vraiment pas.



olivier.