Hibernate intercettore: un'entità intercettato quando un elemento di raccolta aggiornata

StackOverflow https://stackoverflow.com/questions/1568192

  •  21-09-2019
  •  | 
  •  

Domanda

Ho bisogno di sapere come posso impostare Hibernate (...) per ottenere il seguente problema:

Ho una bidirezionale (composizione) uno-a-molti (a.bs è un oggetto Set e b.a è un oggetto A). Quando carico "a" da DB e aggiorno uno dei suoi "BS" Ho bisogno Hiernate intercettare un soggetto quando saveOrUpdate A.

Codice:

public class A {
   Set<B> bs = new HashSet<B>();
   // ... other fields and setters/getters
}
public class B {
   A a = null;
   // ... other fields and setters/getters
}

Caso d'uso:

A a = load("idA"); // load A from DB
B b = s.getBById("idB"); // get a B element of A
b.setName("blablabla"); // update a field of B
saveOrUpdate(a); // persist A entity with its Bs (including modified B)

La modifica viene eseguita in quanto il (mini) modello è stato annotato correttamente.

Il problema è che il mio intercettore rileva solo il cambiamento di soggetto B, ma non ho bisogno di A. rilevare un cambiamento perché ho bisogno di aggiornare le informazioni di controllo.

Altro punto di vista è: ho bisogno di ottenere Un'entità via B e aggiornarlo. In realtà, posso ottenere A da B, ma il cambiamento non viene mantenuto ...

Semplificare la domanda: Devo modificare un soggetto (fissare una data) quando il mio intercettore intercetta entità B. Si worksfine in onSave ma non in onFlushDirty. Perché?

Si tratta di: Quando B viene aggiornato, viene intercettato (onFlushDirty). Il corpo del metodo di onFlushDirty, tra le altre cose, fare questo:

b.getA().setLastModifyDate(new Date());

Quindi, in quel momento, un ente, che è collegato alla sessione, dovrebbe diventato sporco, quindi si dovrebbe sollevare un'azione intercettazioni ... voglio dire, il metodo onFlushDirty dovrebbe essere chiamato di nuovo, il suo tempo per un'entità. Ho sbagliato? Ma, in ogni caso, A.lastModifyDate dovrebbe essere aggiornato ... e questo non sta accadendo !!!

A seguito mostro il comportamento effettivo della mia applicazione:

  1. creo un oggetto A
  2. creo un oggetto B e mi associo alla A
  3. persisto A => A.lastModifyDate è la data corretta ( OK )

  4. creo un oggetto A

  5. creo un oggetto B e mi associo alla A
  6. persisto A => A.lastModifyDate è la data corretta ( OK )
  7. I caricare l'oggetto B, aggiorno e persisto B -> A.lastModifyDate è la data corretta ( OK )

  8. creo un oggetto A

  9. creo un oggetto B e mi associo alla A
  10. persisto A => A.lastModifyDate è la data corretta ( OK )
  11. I caricare un oggetto, aggiorno il suo oggetto B ed io persisto A -> A.lastModifyDate non la data corretta ( KO )

  12. creo un oggetto A

  13. creo un oggetto B e mi associo alla A
  14. persisto A => A.lastModifyDate è la data corretta ( OK )
  15. I caricare un oggetto, aggiorno campo qualsiasi di A e anche il suo oggetto B ed io persisto A -> A.lastModifyDate non la data corretta ( KO )

  16. creo un A oggetto e persisto esso.

  17. I caricare un oggetto, mi associo ad essa un nuovo oggetto B ed io persisto A => A.lastModifyDate è la data corretta ( OK )

  18. creo un A oggetto e persisto esso.

  19. I caricare un oggetto, aggiorno campo qualsiasi di A, mi associo ad essa un nuovo oggetto B ed io persisto A => A.lastModifyDate è la data corretta ( OK )

Qualche idea?

Grazie!

È stato utile?

Soluzione

Devi usare onCollectionUpdate per risolvere il problema

Altri suggerimenti

Ok, quindi se (come hai detto nel tuo commento) si sta utilizzando un vero e proprio Interceptor allora non sono abbastanza sicuro che cosa si intende per 'rileva unico cambiamento in B, non a'. E 'fino a tuo l'attuazione del Interceptor per rilevare tutto ciò che si desidera rilevare.

Prendendo il vostro esempio di cui sopra, quando si chiama il metodo session.saveOrUpdate(a) onSave() del vostro intercettore sta per essere invocato sia per A e B (supponendo che l'impostazione appropriata a cascata che è presumibilmente lì visto che hai detto b viene salvato). Questo, naturalmente, presuppone che A è, infatti, stato modificato (e quindi è stato trovato per essere sporco). Modifica B solo non farà una sporca meno che l'associazione non è stato dichiarato come inversa. In tal caso è possibile fare ciò che deve essere fatto quando onSave() viene richiamato per la B o la vostra può agganciare al metodo findDirty() che verrà richiamato per tutte le entità attualmente in sessione. Si noti, tuttavia, che può essere chiamato più di una volta -. In pratica su ogni filo, piuttosto che su saveOrUpdate()

se si vuole farlo funzionare utilizzando onFlushDirty, è necessario svuotare manualmente la sessione dopo saveOrUpdate (a); ciò assicurerà alcun aggiornamento in un oggetto persistente otterrà in db commettere; se la vostra su auto modalità di scarico, commettere farà scattare un altro filo che troverà la controllante come sporca. altrimenti l'oggetto non otterrà salvare becoz l'intercettore salverà solo solo l'entità modificato corrente.

ho un caso simile in cui ho bisogno di aggiornare i campi di audit della controllante da una collezione bambino. la differenza è im mio servizio è solo salvando l'elenco dei collezione bambino escludendo l'entità padre.

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