Pregunta

Tengo un objeto APP que tiene una relación de muchos a muchos como la siguiente:

@Entity
public class Role {
    //...

    @ManyToMany(fetch=FetchType.EAGER)
    @JoinTable(
    name="RolePrivilege",
    joinColumns=
        @JoinColumn(name="role", referencedColumnName="ID"),
    inverseJoinColumns=
        @JoinColumn(name="privilege", referencedColumnName="ID")
    )
    private Set<Privilege> privs;
}

No es un objeto de la APP para RolePrivilege, así que no estoy seguro de cómo escribir una consulta JPQL para borrar las entradas del campo privs de un objeto de función. Por ejemplo, he intentado esto, pero no funciona. Se queja de que Role.privs no está asignada.

DELETE FROM Role.privs p WHERE p.id=:privId

No estoy seguro de qué más probar. Podría, por supuesto, acaba de escribir una consulta nativa que elimina de la tabla de unión RolePrivilege. Sin embargo, me preocupa que al hacerlo mal interactuar con objetos en caché local que no se actualizan por la consulta nativa.

¿Es incluso posible escribir JPQL para eliminar entradas de una tabla de unión como esta? Si no es así que sólo puede cargar todos los objetos de función y eliminar entradas de la colección privs de cada uno y luego persistir cada función. Pero parece tonto para hacer eso si una consulta sencilla JPQL va a hacer todo de una vez.

¿Fue útil?

Solución

La actualización JPQL y DELETE necesitan para hacer referencia a un nombre de entidad, no un nombre de tabla, por lo que creo que estás fuera de suerte con el enfoque que usted ha sugerido.

En función de su proveedor de APP, se podría eliminar las entradas de la joinTable utilizando una simple declaración de SQL en bruto (debe ser 100% portátil) y luego interactuar mediante programación con el API de proveedor de caché para desalojar a los datos. Por ejemplo, en hibernación puede llamar a desalojar a () de caducar todas las colecciones "Role.privs" desde el segundo nivel de caché:

sessionFactory.evictCollection("Role.privs", roleId); //evict a particular collection of privs
sessionFactory.evictCollection("Role.privs"); //evict all privs collections

Por desgracia yo no trabajo con las API JPA suficientes para saber con seguridad lo que está apoyado con exactitud.

Otros consejos

También estaba buscando un enfoque JPQL eliminar una relación de muchos a muchos (contenida en una tabla de unión). Obviamente, no hay concepto de tablas en un ORM, por lo que no se puede utilizar DELETE ... Pero me gustaría que hubiera un operador especial para estos casos. Algo así como vincular o desvincular. Tal vez una característica futuro?

De todos modos, lo que he estado haciendo para lograr esta necesidad ha sido trabajar con las colecciones implementadas en los beans de entidad, las que se asignan las relaciones de muchos a muchos.

Por ejemplo, si me dieron una clase Student, que tiene una relación de muchos a muchos con cursos:

@ManyToMany
private Collection <Courses> collCourses;

construyo en la entidad un getter y setter para esa colección. Entonces, por ejemplo, de un EJB, recupero la colección mediante el captador, añadir o eliminar el curso deseado, y finalmente, el uso del colocador para asignar la nueva colección. Y se hace. Funciona perfectamente.

Sin embargo, mi principal preocupación es el rendimiento. Un ORM se debe evitar que una enorme caché de todos los objetos (si no me equivoco), pero incluso utilizarlo para trabajar más rápido, me pregunto si la recuperación de todos y cada elemento de una colección es realmente eficaz ...

Debido a que para mí es lo más ineficaz como recuperar los registros de una tabla y después de filtrar utilizando Java puro en lugar de un lenguaje de consulta que trabaja directa o undirectly con el motor de base de datos interna (SQL, JPQL ...).

Java es un lenguaje orientado a objetos y el punto central de ORM es para ocultar los detalles de tales tablas de combinación y de usted. En consecuencia, incluso contemplando la eliminación de una tabla de unión sin considerar las consecuencias sería extraño.

No, no puedes hacerlo con JPQL, es decir para las entidades.

Recuperar las entidades en cada extremo y limpiar sus colecciones. Esto eliminará la unión entradas mesas. Orientado a objetos.

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