Frage

Ich habe ein PPV-Objekt, das eine viele-zu-viele-Beziehung wie folgt hat:

@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;
}

Es gibt keine JPA-Objekt für RolePrivilege, also bin ich nicht sicher, wie eine JPQL Abfrage schreiben Einträge aus dem privs Feld einer Rolle Objekt zu löschen. Zum Beispiel habe ich das versucht, aber es funktioniert nicht. Sie wirft Role.privs nicht abgebildet wird.

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

Ich bin nicht sicher, was anderes zu versuchen. Ich könnte natürlich schreiben Sie einfach eine native Abfrage, die RolePrivilege aus der Join-Tabelle löscht. Aber ich mache mir Sorgen, dass so schlecht mit lokal zwischengespeicherten Objekten würden interagieren zu tun, die nicht durch die native Abfrage aktualisiert werden.

Ist es sogar möglich, JPQL zu schreiben wie diese Einträge aus einer Join-Tabelle zu entfernen? Wenn nicht, kann ich laden einfach alle Rollenobjekte und entfernen Sie Einträge aus der privs Sammlung von jedem und dann jede Rolle bestehen. Aber es albern scheint, dass zu tun, wenn eine einfache Abfrage JPQL alles auf einmal tun.

War es hilfreich?

Lösung

Das JPQL Update und Delete-Anweisungen zu einem Entity Namen verweisen müssen, kein Tabellennamen, so dass ich glaube, Sie kein Glück mit dem Ansatz, den Sie vorgeschlagen haben.

auf Ihren JPA-Provider abhängig, können Sie die Einträge aus dem JoinTable löschen könnten eine einfache raw SQL-Anweisung (sollte 100% tragbar sein) und dann mit dem Cache-Provider API programmatisch interagieren, um die Daten zu vertreiben. Zum Beispiel in dem Ruhezustand können Sie evict () rufen alle „Role.privs“ Sammlungen aus der 2. Level-Cache ablaufen:

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

Leider sicher zu wissen, dass ich nicht genug mit dem JPA-APIs arbeiten, was genau unterstützt wird.

Andere Tipps

Ich war auch auf der Suche nach einem JPQL Ansatz eine many-to-many-Beziehung (enthalten in einer Verbindungstabelle) zu löschen. Natürlich gibt es kein Konzept von Tabellen in einem ORM, so können wir nicht verwenden DELETE-Operationen ... Aber ich wünsche es ein spezieller Operator für diese Fälle war. So etwas wie LINK und UNLINK. Vielleicht eine Zukunft Feature?

Wie auch immer, was ich habe, dieses Bedürfnis zu erreichen getan hat mit den Sammlungen in den Entity Beans, diejenigen, die die many-to-many-Beziehungen abzubilden umgesetzt zu arbeiten.

Zum Beispiel, wenn ich bekomme eine Klasse Schüler, die eine many-to-many-Beziehung mit Plätzen hat:

@ManyToMany
private Collection <Courses> collCourses;

Ich baue in der Einheit einen Getter und Setter für diese Sammlung. Dann wird zum Beispiel aus einer EJB, Abrufen I die Sammlung des Getters verwendet wird, hinzuzufügen oder zu dem gewünschten Kurs zu entfernen, und schließlich Verwenden die Setter, um die neue Sammlung zuweisen. Und es gemacht wird. Es funktioniert perfekt.

Doch meine Hauptsorge ist die Leistung. Ein ORM sollte einen großen Cache aller Objekte halten (wenn ich mich nicht irre), wobei jedoch es noch schneller zu arbeiten, ich frage mich, ob aus einer Sammlung alles und jedes Element Abrufen ist wirklich effektiv ...

für mich Weil es so viel ineffizient, da die Register aus einer Tabelle abrufen und Nachfilter sie unter Verwendung von reinem Java anstelle einer Abfragesprache, die mit den internen DB-Engine direkt oder undirectly arbeitet (SQL, JPQL ...).

Java ist eine objektorientierte Sprache und der ganze Sinn der ORM ist Details der Join-Tabellen und solche, von Ihnen zu verbergen. Folglich sogar von einer Join-Tabelle betrachten Löschung ohne auf die Folgen seltsam wäre.

Nein, Sie es mit JPQL nicht tun können, das heißt für Unternehmen.

Rufen Sie die Einheiten an jedem Ende und ihre Sammlungen löschen. Dies entfernt die Tabelleneinträge verbinden. Objektorientiert.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top