Así que tener una base de JSF Datatable, el respectivo parte es:

<h:dataTable value="#{actorTableBackingBean.allActors}" var="actor">

    <h:column headerText="Actor Name" sortBy="#{actor.firstName}">
        <h:outputText value="#{actor.firstName}" />
    </h:column>

    <h:column>
        <h:form>
            <h:commandButton value="Delete Actor"
                             action="#{actorTableBackingBean.deleteActor(actor)}"/>
        </h:form>
    </h:column>

    <h:column>
        <h:form>
            <h:commandButton value="Randomize Actor Name"
                             action="#{actorTableBackingBean.editActor(actor)}"/>
        </h:form>
    </h:column>

</h:dataTable>

Y esto es lo que ActorTableBackingBean parece:

@Named
@RequestScoped
public class ActorTableBackingBean implements Serializable {

    @Inject
    ActorDao actorDao;

    private List<Actor> allActors;

    public List<Actor> getAllActors() {
        return allActors;
    }

    @PostConstruct
    public void fillUp(){
        allActors = actorDao.getAllT();
    }

    public String deleteActor(Actor a){
        removeActor(a);
        return "/allActors.xhtml";
    }

    private String removeActor(Actor a){
        try{
            actorDao.deleteActor(a);
            return null;
        }catch (Exception e){
            return null;
        }
    }

    public String editActor(Actor actor){
        actor.setFirstName("SomeRandonName");
        actorDao.editActor(actor);
        return "/allActors.xhtml";
    }

}

Y finalmente ActorDao:

@Stateless
public class ActorDao extends GeneralDao<Actor> implements Serializable {

    @Override
    protected Class<Actor> getClassType() {
        return Actor.class;
    }

    @Override
    public Actor getWithId(int id){
        TypedQuery<Actor> typedQuery =
                em.createQuery("Select a From Actor a WHERE a.actorId =" + id,Actor.class);
        return typedQuery.getSingleResult();
    }

    public void editActor(Actor a){
        em.merge(a);
    }

    public void deleteActor(Actor a){
        em.remove(a);
    }

}

Así como usted puede ver, editar Actor llamadas em.combinación de(a) y este funciona bien.
Sin embargo em.quitar(a) devolverá:

Caused by: java.lang.IllegalArgumentException: Entity must be managed to call remove: com.tugay.sakkillaa.model.[email protected], try merging the detached and try the remove again.

Incluso si intento:

 public void deleteActor(Actor a){
    em.merge(a); 
    em.remove(a);
 }

Yo todavía estoy recibiendo la misma excepción.

Entonces, ¿cómo funciona para la edición de la fila, pero no para eliminarlo?

Única forma en que podía hacer el trabajo fue:

public void deleteActor(Actor a){
    Actor actorToBeRemoved = getWithId(a.getActorId());
    em.remove(actorToBeRemoved);
}

¿Qué es lo que estoy haciendo mal, o no es capaz de entender?

InformationsquelleAutor Koray Tugay | 2013-07-06

1 Comentario

  1. 41

    La combinación() el método es el siguiente: se toma un desprendimiento de la entidad, las cargas de la adjunta de la entidad con el mismo ID de la base de datos, copias el estado de la entidad separada conectada a la una, y devuelve el adjunto de la entidad. Como se nota en esta descripción, el desprendimiento de la entidad no se modifica en absoluto, y no se apegan. Esta es la razón por la que usted consigue la excepción.

    Que no se es si lo hizo

    public void deleteActor(Actor a){
        a = em.merge(a); //merge and assign a to the attached entity 
        em.remove(a); //remove the attached entity
    }

    Que dijo, la fusión es completamente innecesario, ya que todo lo que quiero hacer es quitar la entidad. La última solución es buena, a excepción de lo que realmente cargas de la entidad de la base de datos, que también es innecesario. Simplemente debe hacer

    public void deleteActor(Actor a){
        Actor actorToBeRemoved = em.getReference(Actor.class, a.getActorId());
        em.remove(actorToBeRemoved);
    }

    Nota que su getWithId() método no es eficiente, e innecesariamente complejo. Usted debe reemplazarla con

    public Actor getWithId(int id){
        return em.find(Actor.class, id);
    }

    que el primer nivel de uso de la caché (y, potencialmente, en el segundo nivel uno) para evitar consultas innecesarias.

    • Gracias Por este claro y de Gran respuesta.
    • Perdón, ¿puede explicar cómo em.quitar(em.contiene(entidad) ? entidad : em.combinación de(entidad)); obras en BalusC ‘s respuesta en: stackoverflow.com/questions/17027398/… no es esta la misma situación? La fusión no debe ser suficiente, estoy en lo cierto?
    • si el em no contiene la entidad, esta declaración boild abajo para em.remove(em.merge(entity)), que significa: quitar la entidad devuelta por em.merge(entity). Por lo que no retire la almohadilla de la entidad devuelto por em.merge().
    • Gracias, tengo…
    • El método em.get(Class<T> entityClass, Object primaryKey) no está disponible. Se supone que el método em.find(Class<T> entityClass, Object primaryKey) en su lugar (en el último fragmento de código)?
    • Esta es una solución simple pero pasé bien durante 2 horas buscando. Es increíble lo fácil que es gestionar DB contenido con JPA.
    • Se em.remove(em.getReference(...)) también el trabajo?

Dejar respuesta

Please enter your comment!
Please enter your name here