Domanda

Modifica 5/11/2011:

Immagino sia un po 'peggio di quello che c'è sotto; nella mia istanza QA distribuita, se aggiorno il dashboard principale un certo numero di volte, alla fine le associazioni di gruppo molti-a-molti del mio utente vengono eliminate. A questo punto, ci sono solo istruzioni select chiamate sul lato server; spero di riuscire a restringere il campo con questi ultimi test.

Originale:

Ciao a tutti. Ho un problema con un oggetto piuttosto complesso; Il problema è il seguente: quando invio l'oggetto dal client al server per essere salvato, apparentemente sta cancellando in modo casuale le relazioni molti-a-molti sugli oggetti associati. Peggio ancora, non sono in grado di riprodurre il problema da solo, dopo circa due mesi in cui sono stato consapevole del problema. Ho l'app per testare con un gruppo di controllo qualità; usano il programma quotidianamente, entrando due volte nelle applicazioni nuove e legacy. Il problema si presenta anche tre volte al giorno.

Farò del mio meglio per fornire quanti più dettagli possibile e apprezzerò molto chiunque dia un'occhiata!

Il framework dell'app è GWT 2.1 + Gilead + Hibernate 3 + MySQL InnoDB. Lascio che Hibernate gestisca qualsiasi cascata ecc., Quindi nessuno è definito nel DB, sebbene tutte le chiavi esterne siano impostate nel DB.

Ecco alcuni estratti dalle mappature:

<hibernate-mapping>
 <class name="com.example.domain.Close" table="CLOSE">

 <many-to-one name="updateUser"
class="com.example.domain.User"
column="LAST_UPDATE_USER"/>
 </class>
</hibernate-mapping>

<hibernate-mapping>
  <class name="com.example.domain.User" table="USER" batch-size="25">
    <set name="groups" table="USER_GROUP" lazy="true" batch-size="25">
      <key column="USER_ID"/>
      <many-to-many column="GROUP_ID" class="com.example.domain.Group"/>
    </set>
  </class>
</hibernate-mapping>

<hibernate-mapping>
  <class name="com.example.domain.Group" 
    table="GROUP" batch-size="25">
    <set name="users" table="USER_GROUP" lazy="true" inverse="true">
      <key column="GROUP_ID"/>
      <many-to-many column="USER_ID" class="com.example.domain.User"/>
    </set>
    <set name="permissions" table="PERMISSION_GROUP" lazy="true" inverse="true">
    <key column="GROUP_ID"/>
    <many-to-many column="PERMISSION_ID" 
      class="com.example.domain.Permission"/>
    </set>

<hibernate-mapping>
  <class name="com.example.domain.Permission" 
      table="PERMISSION">
    <set name="groups" table="PERMISSION_GROUP" lazy="true">
      <key column="PERMISSION_ID"/>
      <many-to-many column="GROUP_ID" 
        class="com.example.domain.Group"/>
    </set>
  </class>
</hibernate-mapping>

Salvare l'oggetto è una semplice chiamata a saveOrUpdate ():

Session session = gileadHibernateUtil.getSessionFactory()
  .getCurrentSession();
session.beginTransaction();
try {
  session.saveOrUpdate(close);
} catch (Exception e) {
  e.printStackTrace();
  session.getTransaction.rollback();
}
session.getTransaction.commit();

return close;

L'oggetto Close "updateUser" è un oggetto caricato quando l'utente accede. Viene caricato con i gruppi e le autorizzazioni associati in modo che il sistema possa concedere / negare l'accesso ai moduli dell'app. Sì

close.setUpdateUser(exampleApp.getUser()); 

prima di rimandare l'oggetto al server.

Ci sono molti altri punti nell'app in cui avviene questo tipo di operazione, ma non causa gli effetti collaterali indesiderati. Probabilmente si riduce alla complessità del codice lato client associato all'oggetto Close, o meglio, alla mia implementazione di esso.

Ho passato così tanto tempo a sfogliare i documenti ufficiali di Hibernate, alla ricerca di eventuali problemi correlati, ecc., Ho pensato che forse fosse un buon momento per chiedere aiuto. Devo prepararmi e continuare a farlo, ma forse solo chiedere mi aiuterà a capirlo.

Non sono sicuro di cos'altro fornire in questo momento che sia rilevante. Si spera che ciò che c'è qui finora abbia rilevanza!

Grazie per l'ascolto!

<”Modifica

May  5 12:18:38 localhost jsvc.exec[10117]: Hibernate: insert into example_dev.RECENT_ITEM (OBJECT_TYPE, OBJECT_ID, DATE, USER_ID) values (?, ?, ?, ?)
May  5 12:18:38 localhost jsvc.exec[10117]: Hibernate: delete from example_dev.PERMISSION_GROUP where PERMISSION_ID=?
May  5 12:18:38 localhost last message repeated 19 times
May  5 12:18:38 localhost jsvc.exec[10117]: Hibernate: delete from example_dev.USER_GROUP where USER_ID=?
May  5 12:18:38 localhost jsvc.exec[10117]: Hibernate: delete from example_dev.USER_DESIGNATION where USER_ID=?

Sembra che le eliminazioni avvengano subito dopo questo inserimento .. le operazioni precedenti sono tutte selezioni. Ma niente in User dovrebbe essere a cascata da RecentItem.

È stato utile?

Soluzione

Dopo molte ricerche, sono giunto ad alcune conclusioni e sono stato in grado di agire. Prima di tutto, dopo un po 'di ricerche sul forum di Gilead ho appreso che non si tratta più di attivamente mantenuto . Avrei dovuto notarlo prima. Nel frattempo, avevo iniziato a leggere di RequestFactory e, dopo un paio di giorni di ricerca, ho deciso che avrei dovuto provare a migrare a questo.

Questo è un progetto piuttosto ampio, circa 50 oggetti di dominio, alcuni con molte associazioni di oggetti. Mi ci sono volute circa 40-50 ore per riscrivere tutto, dall'utilizzo di Gilead + GWT RPC all'utilizzo esclusivo di RequestFactory. Sono abbastanza soddisfatto dei cambiamenti risultanti nel codice e nella struttura. Finora non sono troppo infastidito dal dover creare oggetti proxy DTO e ho colto l'occasione per passare a Annotazioni di ibernazione, eliminando i file di mappatura.

A volte era difficile rifattorizzare il codice per utilizzare i cicli di recupero / modifica / salvataggio richiesti da RequestFactory. Mi ha dato l'opportunità di migliorare parte del codice.

La buona notizia è che il problema è stato risolto. Niente più associazioni molti-a-molti che vengono misteriosamente cancellate. La mia ipotesi migliore è che stavo riscontrando un bug in Gilead, o il mio utilizzo non era corretto, oppure è possibile che abbia risolto un problema durante la migrazione ad Annotations.

Mi sono imbattuto in alcune ottime risorse mentre imparavo RequestFactory + Hibernate, molte tramite StackOverflow (grazie ancora!):

Utilizzo di GWT RequestFactory con Objectify - è stato fantastico avere un'idea di come RequestFactory ha interagito con il backend e alcuni metodi e boilerplate per ridurre il codice.

Si spera che ci siano altri link di seguito .. Sono ancora un noob, quindi ho un numero limitato di collegamenti ipertestuali che posso pubblicare :)

Ho imparato molto e sto diventando fluente in RequestFactory. Farò del mio meglio per tenere gli occhi aperti e dare una mano dove penso di poterlo fare.

Grazie StackOverflow!

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