2015-06-22 32 views
6

Posiadanie sprawy w jednej z moich klas domeny, w której przechowujemy pole przejściowe do bazy danych Mongo w hasłach beforeInsert i afterUpdate, które działa idealnie w następujących warunkach: -Jak sprawdzić isDirty ('transient_fieldName') dla zmiennych przejściowych w Grails

  • Wstawki działają dobrze bez żadnego problemu.
  • Aktualizacje działa dobrze, jeśli jest niemodyfikowana przemijający pole

Problemem jest isDirty działa na właściwości niż przemijające.

Kod jest jak poniżej:

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) 
    } 

} 

Aby poradzić sobie z tym problemem sam stworzyłem isDirtyMongo ('transient_field'). Działa to dobrze do czasu, w którym nieruchoma właściwość jest modyfikowana, jak po nazwieUpdate jest wywoływana tylko dla właściwości przejściowych.

Modified hak jest jak poniżej:

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

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

Więc ostateczny pytanie, jak możemy nazwać hak aktualizacji dla nieustalonych modyfikacji polowych, jak również.

Każda pomoc będzie bardzo ceniona.

+0

O ile wiem, pole przejściowe w stanie hibernacji nie trwa tak, że niemożliwe jest poznanie wartości po dołączeniu. W przypadku hibernacji, pole przejściowe jest po prostu pustą rzeczą. – dgregory

+0

Zgadzam się! Ale mam przypadek wielu baz danych, gdzie chcę potwierdzić isDirty również dla zmiennych przejściowych. na przykład isDirty ('config'), gdzie konfiguracja jest przejściowa. –

Odpowiedz

1

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

Zasadniczo, niech hibernacji myśleć, że wszystkie pola są brudne, jeśli pole przejściowy jest brudna.

Można spróbować zoptymalizować trochę oznaczyć tylko pierwszy obiekt jako zanieczyszczony (bez względu na to, ilu z nich są brudne, jednostka jest brudna, jeśli co najmniej jedna właściwość jest brudna):

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

Jednak to zawsze wyklucza inne właściwości z instrukcji SQL update, jeśli używasz @DynamicUpdate dla tych encji, więc zakładam, że bardziej przejrzystym i spójnym sposobem jest oznaczenie wszystkich właściwości jako brudnych (bez @DynamicUpdate wszystkie właściwości są zawsze zawarte w SQL update oświadczenie mimo to).

+0

Czy ma zastosowanie w Grails? Poza tym, gdzie powinien on zostać zaimplementowany w kompilacji Grails, ponieważ jestem bardzo mniej w Hibernate. Dobra wskazówka zrobi. –

+0

A ja jestem mniej w Grails, ale [to] (http://stackoverflow.com/questions/5424148/is-it-possible-to-map-a-table-name-for-a-domain- object-dynamically-in-grails/5429546 # 5429546) wydaje się być sposobem na zarejestrowanie przechwytywacza Hibernate w Grails. –