2013-07-13 13 views
11

Zastanawiam się, w jaki sposób mogę utworzyć głęboką kopię utrwalonego obiektu z całym jego powiązaniem. Powiedzmy, że mam następujący model.Głęboki klon elementu hibernacji

class Document { 
    String title; 
    String content; 
    Person owner; 
    Set<Citation> citations; 
} 

class Person { 
    String name; 
    Set<Document> documents; 
} 

class Citation { 
    String title; 
    Date date; 
    Set<Document> documents; 
} 

Mam scenariusz, w którym użytkownik może chcieć chwycić kopii danego dokumentu od osoby i sprawić, że dokument jego/jej potem on/ona może zmienić jego treść i nazwę. W tym przypadku mogę wymyślić jeden ze sposobów na wdrożenie tego rodzaju scenariusza, który tworzy głęboką kopię tego dokumentu (wraz z powiązaniami).

A może, jeśli ktoś wie o jakimkolwiek innym sposobie na zrobienie czegoś takiego bez robienia ogromnej kopii danych, ponieważ wiem, że może to być złe dla wydajności aplikacji.

Zastanowiłem się również nad tworzeniem odnośnika do oryginalnego dokumentu, na przykład o atrybucie originalDocument, ale w ten sposób nie będę wiedział, który atrybut (lub być może skojarzenie) został zmieniony.

Odpowiedz

7

Aby wykonać głęboki kopię:

metoda
public static <T> T clone(Class<T> clazz, T dtls) { 
     T clonedObject = (T) SerializationHelper.clone((Serializable) dtls); 
     return clonedObject; 
    } 

To narzędzie daje głęboką kopię podmiotu i można wykonać żądane rzeczy, co chcesz zrobić ze sklonowanego obiektu.

+2

Problem ten może być, nie może obsłużyć zbiory leniwego obciążenia i właściwości wersji. IMHO lepszym sposobem byłoby napisanie metod deep copy w każdej klasie. –

+0

nie może obsłużyć leniwych pól, nie udało się zainicjować leniwego zbierania w nowym sklonowanym obiekcie. –

+0

Możesz użyć Jacksona do serializowania w jsonie w mermory, który obsługuje leniwy załadunek hibernacji (musisz to skonfigurować) –

1

konfiguracja serializacji Jackon do hibernacji:

ObjectMapper mapperInstance 
    Hibernate4Module module = new Hibernate4Module(); 
     module.configure(Hibernate4Module.Feature.FORCE_LAZY_LOADING, false); 

     mapperInstance.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false); 
     mapperInstance.disable(MapperFeature.USE_GETTERS_AS_SETTERS); 
     mapperInstance.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); 
     mapperInstance.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false); 

     mapperInstance.registerModule(module); 

A obok

clone = getMapperInstance().readValue(getMapperInstance().writeValueAsString(this)); 

Ok to kosztować trochę pamięci i procesora ...