2015-06-22 14 views
6

Avere un caso in una delle mia classe di dominio che memorizziamo un campo transitorio a base di dati Mongo in PrimaDiInserire e DopoAggiornamento ganci che funziona perfettamente con i seguenti requisiti: -Come controllare IsDirty ('transient_fieldName') per i campi transitori in Grails

  • Gli inserti funzionano bene senza alcun problema.
  • Aggiornamenti funziona bene se c'è un campo transitorio non modificato

Il problema è IsDirty lavora per proprietà non transitori.

codice è il seguente:

class ResoruceInstance { 
    def configurationService 
    Status status 

    //Transient 
    Map<String, Object> configuration 
    static transients = ['configuration'] 


    public Map<String, Object> getConfiguration() { 
     if(!configuration) 
      configuration = configurationService.get(id, CollectionConstants.RESOURCE_INSTANCE_IDENTIFIER) 

     return configuration 
    } 

    def afterInsert() { 
     configurationService.save(id, CollectionConstants.RESOURCE_INSTANCE_IDENTIFIER, configuration) 
    } 
    def afterUpdate() { 
     if(this.isDirty("configuration")) 
      configurationService.save(id, CollectionConstants.RESOURCE_INSTANCE_IDENTIFIER, configuration) 
    } 

} 

per gestire questo problema ho creato isDirtyMongo ('transient_field'). Funziona bene fino al momento in cui una proprietà non transiente viene modificata poiché afterUpdate viene chiamato solo per le proprietà transitorie.

gancio

modificata è la seguente:

def afterUpdate() { 
      if(this.isDirtyMongo("configuration")) 
       configurationService.save(id, CollectionConstants.RESOURCE_INSTANCE_IDENTIFIER, configuration) 
     } 

boolean isDirtyMongo(String property){ 
//return whether is dirty or not 
} 

Così, l'ultima domanda è come si può chiamare un gancio aggiornamento per le modifiche dei campi transitori pure.

Qualsiasi aiuto sarebbe molto apprezzato.

+0

Per quanto ne so, il campo transitorio in sospensione non persiste, quindi è impossibile conoscere il valore dopo averlo collegato. Nell'evento di ibernazione, il campo transitorio è solo una cosa nulla. – dgregory

+0

Accetto! Ma ho il caso di più database in cui voglio convalidare isDirty anche per i campi transitori. per esempio. isDirty ('config') dove config è transitorio. –

risposta

1

Implementare la Interceptor.findDirty:

public class TransientFieldDirtinessInterceptor extends EmptyInterceptor { 
    @Override 
    public int[] findDirty(Object entity, ..., String[] propertyNames, ...) { 
     if ((entity instanceof EntityToCheck) && isTransientFieldDirty(entity)) { 
      // Just return all fields as dirty 
      int[] result = new int[propertyNames.length]; 
      for(int i = 0; i < result.length; i++) { 
       result[i] = i; 
      } 
      return result; 
     } 
     // Use Hibernate's default dirty-checking algorithm 
     return null; 
    } 
} 

In sostanza, diamo Hibernate pensare che tutti i campi sono sporchi se il campo transitorio è sporco.

Si potrebbe provare a ottimizzare questo un po 'per marcare solo la prima proprietà come sporco (non importa quanti di loro sono sporchi, l'entità è sporca se almeno una proprietà è sporco):

int[] result = new int[1]; 
result[0] = 0; 
return result; 

Tuttavia, questo esclude sempre altre proprietà dall'istruzione SQL update se si utilizza @DynamicUpdate per queste entità, quindi presumo che il modo più chiaro e coerente sia quello di contrassegnare tutte le proprietà come dirty (senza @DynamicUpdate tutte le proprietà sono sempre incluse in SQL update dichiarazione comunque).

+0

È applicabile in Grails? Inoltre, dove dovrebbe essere implementato in una build di Grails poiché sono molto meno in Hibernate. Un buon suggerimento lo farà. –

+0

E io sono molto meno in Grails, :) ma [questo] (http://stackoverflow.com/questions/5424148/is-it-possibile-to-pagina-per-nome-per-a-domain- object-dynamically-in-grails/5429546 # 5429546) sembra essere un modo per registrare un intercettore Hibernate in Grails. –

Problemi correlati