Partage
  • Partager sur Facebook
  • Partager sur Twitter

Problème avec EntityManager.remove (JPA)

    26 juin 2014 à 15:38:56

    Bonjour,

    Dans l'application Web sur laquelle je travaille, j'ai besoin de pouvoir supprimer des lots d'une commande, ce que je fais dans la méthode ci-dessous.

    public void removeBatch() {
    	Map<String, String> params = FacesContext.getCurrentInstance().getExternalContext().getRequestParameterMap();
    	ejb.remove(ejb.merge(order.getBatches().remove(Integer.parseInt(params.get("index")))));
    	order = ejb.merge(order);
    }

    Cette méthode est appelée par le code xhtml suivant :

    <h:commandLink action="#{sessionBean.removeBatch}" styleClass="itemName" value="X">
    	<f:param name="index" value="#{status.index}"/>
    </h:commandLink>

    Mon problème, c'est que l'opération remove ne fonctionne pas :

    Entity must be managed to call remove: entities.Batch@6b2d2eba, try merging the detached and try the remove again.

    Le truc, c'est que normalement mon Batch est bien "managed" puisque je le merge avant de le supprimer (comme c'est d'ailleurs dit dans le message). Une idée de ce qui ne va pas ?

    PS : ah, et peut-être que c'est important, je n'appelle pas les méthodes merge et remove directement sur un EntityManager, ça passe par un EJB ejb de type GenericEJB :

    import javax.ejb.Stateless;
    import javax.persistence.EntityManager;
    import javax.persistence.PersistenceContext;
    
    @Stateless
    public class GenericEJB {
    	@PersistenceContext
    	protected EntityManager em;
    	
    	public <T> T find(Class<T> c, Object key) {
    		return em.find(c,key);
    	}
    	
    	public <T> void remove(T t) {
    		em.remove(t);
    	}
            //etc...
    }
    

    Enfin, il y une relation dans la base de données (table clientorder_batch) entre la classe Batch (qui est le type des objets de order.getBatches()) et la classe ClientOrder (order en est une instance dans mon code).

    -
    Edité par Dici 26 juin 2014 à 15:56:12

    • Partager sur Facebook
    • Partager sur Twitter
      26 juin 2014 à 16:00:47

      Bon, j'ai trouvé par moi-même une façon détournée de faire la chose. Plutôt que de faire merge + remove, je fais find + remove en utilisant l'id de l'instance dont je dispose côté serveur. Cela dit, je reste intéressé par une explication sur le bug que j'avais, qui m'a bouffé pas mal de temps pour rien.
      • Partager sur Facebook
      • Partager sur Twitter
        27 juin 2014 à 17:13:00

        Tu devrais essayer : 

        public void removeBatch() {
            Map<String, String> params = FacesContext.getCurrentInstance().getExternalContext().getRequestParameterMap();
        
            Integer index = Integer.parseInt(params.get("index"));
            order = ejb.merge(order);
            ejb.remove(order.getBatches().get(index));
            order.getBatches().remove(index);
            ejb.update(order);
        
        }



        • Partager sur Facebook
        • Partager sur Twitter
          27 juin 2014 à 17:28:09

          La méthode update n'existe pas sur les EntityManager. De plus ici order.getBatches().get(index) n'est pas "managed" donc ça n'a aucune raison de marcher a priori. Merci tout de même de ta réponse :)
          • Partager sur Facebook
          • Partager sur Twitter
            12 juillet 2017 à 17:34:08

            J'avais le meme probleme.

            Pour info, pour le remove, il faut d'abord faire un merge en re-stockant bien la valeur du merge dans variable initiale.

            t=em.merge(t);

            em.remove(t);

            -
            Edité par SandrineBurgermeister 12 juillet 2017 à 17:34:38

            • Partager sur Facebook
            • Partager sur Twitter
              25 septembre 2017 à 15:33:05

              Pour pouvoir faire remove d'une entité il faut qu'elle soit dans le cache de premier niveau (c.a.d "managed"). C'est la seule, mais nécessaire contraintes. Il y a de multiples façons de faire : find, merge en sont, il y en a d'autres : getResultList, getSingleResult d'une query. Autre possibilité : accéder à l'entité à supprimer en suivant les liens à partir d'une entité (dans le cache, généralement).
              • Partager sur Facebook
              • Partager sur Twitter

              Problème avec EntityManager.remove (JPA)

              × Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
              × Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
              • Editeur
              • Markdown