Mi pregunta aquí es casi similar a la de mi otra pregunta Explícito eliminar en JPA relaciones
pero pensé en la simplificación de que además garantiza respuestas más detalladas.

Imagine que tiene un OneToMany relación entre un padre y un hijo.

@Entity
public class Parent {
    private String name;
    @OneToMany(mappedBy="owner",cascade=CascadeType.ALL, fetch=FetchType.EAGER)
    private List<Child> children;
}
@Entity
public class Child {
    private String name;
    @ManyToOne
    private Parent owner;
}

En mi interfaz de usuario, estoy mostrando una lista de los padres. El usuario puede elegir uno de los padres y que él/ella puede editar la lista de sus hijos.
Para mostrar esto, he utilizado un currentParent variable para representar la matriz actual edición.
El usuario puede elegir agregar/editar los niños del nombre.

Al hacer clic en un botón, quiero salvar a los niños nuevos de la lista mediante una llamada a EJB.

@ViewScoped
public class MyBean(){
    private Parent currentParent;
    @EJB
    private MyEJB myEJB;

    public void saveChanges(){
        myEJB.save(currentParent);
    }
}

Mi llamada EJB se parece a esto.

@Stateless
public class MyEJB{
    @PersistenceContext(unitName = "MyPU")
    private EntityManager em;

    public void save(Parent parentNew){
        Parent pOld = em.find(entityClass,  p.getId());
        if(pOld !=null){
            pOld.setName(parentNew.getName());
            pOld.setChildren(parentNew.getChildren());
            em.merge(pOld);
        }
    }
}

Mi problema es que soy capaz de cambiar el nombre de los padres, pero los cambios a los niños de la lista no se refleja en la DB.
No alterar o ejecutar cualquier SQL para eliminar/actualizar/añadir a los niños.

Lo que podría ser la causa?

ACTUALIZACIÓN

Bien después de un poco de ensayo y error y la lectura a través de diferentes enlaces, parece que la configuración de la orphanRemoval opción en mi @onetomany iba a solucionar mi problema. Eclipselink elimina automáticamente los huérfanos filas durante la fusión.

Tanto para JPA complejidad..

@Entity
public class Parent {
    private String name;
    @OneToMany(mappedBy="owner",cascade=CascadeType.ALL, fetch=FetchType.EAGER,orphanRemoval = true)
    private List<Child> children;
}
Tal vez esto le ayudará a: stackoverflow.com/questions/10656765/…
Hola, no estoy seguro de si tengo la respuesta a partir de ese vínculo, por lo que decir que tengo un bucle a través de la recopilación y guardar uno por uno? En realidad pensé que eclipselink va a controlar el ahorro de mi colección? Así, por ejemplo tengo 5 niños en una entidad y, a continuación, he editado con dos hijos, cuando yo llame a la operación de combinación, se encargará de eliminar/agregar las filas. Gracias

OriginalEl autor Mark Estrada | 2012-10-31

2 Comentarios

  1. 6

    Este es un problema estándar de mezcla. Los cambios a los objetos secundarios de la colección se recogen.

    La combinación de llamada sólo puede cascada sobre los objetos que están en la lista, por lo que los cambios a los objetos que no están en la lista de perderse. Por desgracia, la oneToMany no es dueño de la relación: la del niño ManyToOne. Para que el niño entidades necesitan ser combinados para que el cambio sea visto y empujó a la base de datos. Niño entidades son objetos independientes y necesitan ser combinadas de forma individual cuando se cambian. Que, o añadido a un padre diferente/árbol para conseguir fusionado.

    Hola, gracias por la info, entonces, ¿qué sugiere usted que debo hacer?
    Cualquier número de opciones. Uno sería para agregarlos a un padre diferente si es posible. O si no puede ser independiente de sus padres, los marca con huérfana de eliminación para que se borran cuando se eliminan las referencias. O la manija de la diferencia en la colección en la combinación de llamar a los padres por encontrar a los padres primero y la fijación de los niños que faltan a partir de que el objeto pasa a combinar – esto incluso podría ser factible en un evento. o simplemente asegúrese de que la aplicación llama a la fusión en los niños se quita de un padre.

    OriginalEl autor Chris

  2. 1

    Su pregunta What could be the cause?. La causa es el valor de contenido de parentNew. Si el parentNew es uno de los siguiente causa, no efecto de actualización/a hijo.

    1. Ninguna instancia de referencia de los padres y el niño de prensa de la visa. —> lanzará la excepción.
    2. Parent parámetro valor nulo o vacío lista de Clild –> Este va a ser su causa.
    3. Child no se actualiza el nombre de la interfaz de usuario.–> Este va a ser su causa.

    Ejemplo. Yo de escritura rápida. Es ACEPTAR.

    Ya existen datos en la DB

    Parent                      Child
    ==================    =======================================
    'P001', 'Parent 1'   'C002', 'Child 2', 'P001'
                         'C003', 'Child 3', 'P001'
                         'C001', 'Child 1', 'P001'

    Después De Upldated:

    Parent                      Child
    ==================          =======================================
    'P001', 'Update Parent 1'   'C002', 'Update Child 2', 'P001'
                                'C003', 'Update Child 3', 'P001'
                                'C001', 'Update Child 1', 'P001'
    
    List<Child> clidList = new ArrayList<Child>();
    Parent parent = new Parent("P001", "Update Parent 1", clidList);
    Child c1 = new Child("C001", "Update Child 1", parent);
    Child c2 = new Child("C002", "Update Child 2", parent);
    Child c3 = new Child("C003", "Update Child 3", parent);
    clidList.add(c1);
    clidList.add(c2);
    clidList.add(c3);
    
    Parent existingParent = em.find(Parent.class, parent.getId());
    existingParent.setName(parent.getName());
    existingParent.setChildren(parent.getChildren());
    em.merge(existingParent);

    OriginalEl autor Zaw Than oo

Dejar respuesta

Please enter your comment!
Please enter your name here