Domanda

Ho un oggetto dell'APP, che ha una relazione molti-a-molti in questo modo:

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

non è un oggetto JPA per RolePrivilege, quindi non sono sicuro di come scrivere una query JPQL per eliminare le voci dal campo privs di un oggetto di ruolo. Per esempio, ho provato a farlo, ma non funziona. Si lamenta che Role.privs non è mappata.

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

Non sono sicuro che altro per provare. Potrei naturalmente solo scrivere una query nativo che cancella dalla tabella unirsi RolePrivilege. Ma, io sono preoccupato del fatto che così facendo interagire male con gli oggetti memorizzati nella cache locale, che non sarebbe stato aggiornato dalla query nativo.

E 'anche possibile scrivere JPQL per rimuovere le voci da una tabella unirsi come questo? Se non riesco a caricare solo tutti gli oggetti Ruolo e rimuovere le voci dalla collezione privs di ciascuno e quindi persistono ogni ruolo. Ma sembra sciocca da fare che se una semplice query JPQL farà tutto in una volta.

È stato utile?

Soluzione

L'aggiornamento JPQL e DELETE devono fare riferimento a un nome di entità, non è un nome di tabella, quindi penso che sei fuori di fortuna con l'approccio che hai suggerito.

A seconda del provider JPA, è possibile eliminare le voci dalla JoinTable utilizzando una semplice istruzione SQL prime (dovrebbe essere portatile 100%) e poi a livello di codice di interagire con il vostro fornitore di cache API di sfrattare i dati. Per esempio in Hibernate è possibile chiamare sfrattare () per scadere tutte le collezioni "Role.privs" dalla cache di 2 ° livello:

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

Purtroppo io non lavoro con le API JPA abbastanza per sapere con certezza che cosa esattamente è supportato.

Altri suggerimenti

Mi è stato anche alla ricerca di un approccio JPQL per eliminare una relazione molti-a-molti relazione (contenuto in una tabella di giunzione). Ovviamente, non c'è alcun concetto di tabelle in un ORM, quindi non possiamo usare DELETE ... ma vorrei che ci fosse un operatore speciale per questi casi. Qualcosa di simile a collegare e scollegare. Forse una caratteristica futuro?

In ogni caso, quello che ho fatto per raggiungere questo bisogno è stato quello di lavorare con le collezioni implementate nei bean di entità, quelli che mappano i molti-a-molti rapporti.

Per esempio, se ho ottenuto uno Studente classe che ha una relazione molti-a-molti relazione con Corsi:

@ManyToMany
private Collection <Courses> collCourses;

I costruire nell'entità un getter e setter per quella collezione. Quindi, per esempio da un EJB, posso recuperare la collezione utilizzando il getter, aggiungere o rimuovere la rotta desiderata, e, infine, utilizzare il setter per assegnare la nuova collezione. E il gioco è fatto. Funziona perfettamente.

Tuttavia la mia preoccupazione principale è la performance. Un ORM si suppone di mantenere una cache enorme di tutti gli oggetti (se non mi sbaglio), ma anche di utilizzarlo a lavorare più velocemente, mi chiedo se il recupero di tutti ed ogni elemento da una collezione è veramente efficace ...

Perché per me è il più inefficiente come il recupero dei registri da una tabella e post-filtrarli usando soltanto Java al posto di un linguaggio di query che lavora direttamente o indirettamente con il motore DB interna (SQL, JPQL ...).

Java è un linguaggio orientato agli oggetti e il punto di ORM è quello di nascondere i dettagli di unire le tabelle e tali da voi. Di conseguenza, anche contemplando la cancellazione da una tabella di join senza considerare le conseguenze sarebbe strano.

No non è possibile farlo con JPQL, vale a dire per le entità.

Recuperare le entità alle due estremità e cancellare le loro collezioni. Questo eliminerà il join tabelle voci. Orientata agli oggetti.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top