Pregunta

Tengo las siguientes entidades hibernadas (simplificadas):

@Entity
@Table(name = "package")
public class Package {
    protected Content content;

    @OneToOne(cascade = {javax.persistence.CascadeType.ALL})
    @JoinColumn(name = "content_id")
    @Fetch(value = FetchMode.JOIN)
    public Content getContent() {
        return content;
    }

    public void setContent(Content content) {
        this.content = content;
    }

}


@Entity
@Table(name = "content")
public class Content {
    private Set<Content> subContents = new HashSet<Content>();
    private ArchivalInformationPackage parentPackage;

    @OneToMany(fetch = FetchType.EAGER)
    @JoinTable(name = "subcontents", joinColumns = {@JoinColumn(name = "content_id")}, inverseJoinColumns = {@JoinColumn(name = "elt")})
    @Cascade(value = {org.hibernate.annotations.CascadeType.DELETE, org.hibernate.annotations.CascadeType.REPLICATE})
    @Fetch(value = FetchMode.SUBSELECT)
    public Set<Content> getSubContents() {
        return subContents;
    }

    public void setSubContents(Set<Content> subContents) {
        this.subContents = subContents;
    }

    @ManyToOne(cascade = {CascadeType.ALL})
    @JoinColumn(name = "parent_package_id")
    public Package getParentPackage() {
        return parentPackage;
    }

    public void setParentPackage(Package parentPackage) {
        this.parentPackage = parentPackage;
    }

}

Entonces hay un paquete, que tiene un contenido "superior". El contenido superior se vincula al paquete, con Cascade configurado para todos. El contenido superior puede tener muchos contenidos "sub", y cada subcontente puede tener muchos subcontentes propios. Cada subcontente tiene un paquete principal, que puede o no ser el mismo paquete que el contenido superior (es decir, una relación de muchos a uno para el paquete de contenido).

Se requiere que las relaciones sean muchos (paquete a contenido) y ManyTomany (contenido a subcontentes), pero por el caso estoy probando actualmente cada subcontente solo se relaciona con un paquete o contenido.

El problema es que cuando elimino un paquete y enjuague la sesión, recibo un error de hibernación indicando que estoy violando una restricción de clave extranjera en la mesa. subcontents, con un particular content_id todavía referenciado desde la tabla subcontents.

He probado específicamente (recursivamente) eliminar el contenido antes de eliminar el paquete, pero obtengo el mismo error.

¿Hay alguna razón por la cual este árbol de entidad no se está eliminando correctamente?

EDITAR: Después de leer respuestas/comentarios, me di cuenta de que un contenido no puede tener múltiples paquetes, y un subcontente no puede tener múltiples contenidos principales, por lo que he modificado las anotaciones de ManyOne y ManyTomany a Onetoone y Onetomany. Lamentablemente, eso no solucionó el problema.

También he agregado el enlace bidireccional desde el contenido al paquete principal que dejé fuera del código simplificado.

¿Fue útil?

Solución 2

El problema resultó ser causado por el hecho de que estaba enjuagando y limpiando la sesión después de eliminar cada paquete, y debido a las dependencias circulares en el modelo, no todo se estaba eliminando. Se requieren la descarga y el claro porque están involucrados conjuntos de datos muy grandes. Al final, lo cambié para que se construya un conjunto de todas las entidades que dependen del paquete actual (que puede incluir otros paquetes) y luego se elimina antes de llamar al ras y claro.

Otros consejos

Si entiendo correctamente, según el mapeo ManyToone, un contenido tiene muchos paquetes, y supongo que eliminó el campo de colección de "paquetes" de su clase de contenido en su código simplificado anterior.

Entonces, para su campo de colección de "paquetes", ¿tiene un eliminación de cascade (al igual que lo que tiene en sus subcontentes)? Si lo haces, entonces creo que debería funcionar. Cuando elimina el contenido de la raíz, debe realizar Cascade Eliminar en cada subcontente, y cada contenido realizará Cascade Eliminar en el paquete.

¿Eso funciona?

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top