(netbeans) question de base concernant la persistance
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:
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:
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:
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:
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.