2012-06-22 11 views
7

używam funkcji, aby uzyskać dostęp do dokumentu konfiguracji:Jaki jest najlepszy sposób na recykling obiektów Domino w Java Beans

private Document lookupDoc(String key1) { 
    try { 
     Session sess = ExtLibUtil.getCurrentSession(); 
     Database wDb = sess.getDatabase(sess.getServerName(), this.dbname1); 
     View wView = wDb.getView(this.viewname1); 
     Document wDoc = wView.getDocumentByKey(key1, true); 
     this.debug("Got a doc for key: [" + key1 + "]"); 
     return wDoc; 
    } catch (NotesException ne) { 
     if (this.DispLookupErrors) 
      ne.printStackTrace(); 
     this.lastErrorMsg = ne.text; 
     this.debug(this.lastErrorMsg, "error"); 
    } 
    return null; 
} 

W innej metodzie używać tej funkcji, aby uzyskać dokument:

Document wDoc = this.lookupDoc(key1); 

if (wdoc != null) { 
    // do things with the document 
    wdoc.recycle(); 
} 

Czy należy poddawać recyklingowi bazę danych i wyświetlać obiekty podczas recyklingu obiektu Document? A może należy je poddać recyklingowi, zanim funkcja zwróci dokument?

Próba zieleni mój kod ...

/newbs

+2

Jeden dodatkowy komentarz oprócz doskonałej odpowiedzi Tima: (o wiele) szybszy sposób na odzyskanie określonego dokumentu za pomocą wywołania db.getDocumentByUNID(). Jeśli więc chcesz pobrać ten sam dokument kilka razy, przy pierwszym połączeniu możesz go pobrać z widoku i zapisać jego identyfikator UNID w zmiennej prywatnej. W przypadkowych połączeniach można następnie użyć tego identyfikatora UNID, aby go odzyskać. –

+0

@ Mark: Wcześniej już zaimplementowałem buforowanie danych w odpowiednich zmiennych zakresu po przeczytaniu dokumentu, więc rzadko trzeba ponownie czytać dokument, dopóki zmienne zakresu nie znikną ... W niektórych przypadkach informacje w Zmienna scoped zawiera UNID, dzięki czemu ponowne uzyskanie dostępu do dokumentu jest tak szybkie jak to możliwe./Newbs – Newbs

Odpowiedz

21

Najlepszym rozwiązaniem jest recykling wszystkich obiektów Domino podczas zakresu, w którym zostały utworzone. Jednak recykling dowolnego obiektu automatycznie przetwarza wszystkie obiekty "pod" nim. Dlatego w twojej przykładowej metodzie, nie możesz przerobić wDb, ponieważ to również spowodowałoby recykling wDoc, więc zwrócisz uchwyt Recycled Document.

Jeśli chcesz się upewnić, że nie masz przecieków w pamięci, najlepiej poddawać recyklingowi obiekty w odwrotnej kolejności (np. Najpierw dokument, a następnie widok, a następnie bazę danych). Zwykle wymaga to strukturyzowania twoich metod w taki sposób, abyś robił cokolwiek potrzebujesz/z obiektem Domino wewnątrz jakakolwiek metoda uzyska uchwyt.

Na przykład, zakładam, że zdefiniowałeś metodę pobierania dokumentu konfiguracyjnego, abyś mógł pobrać z niej wartość ustawień konfiguracyjnych. Tak więc, zamiast metody zwrotu dokumentu, być może byłoby lepiej, aby zdefiniować metody zwracają wartość artykuł:

private Object lookupItemValue(String configKey, itemName) { 
    Object result = null; 
    Database wDb = null; 
    View wView = null; 
    Document wDoc = null; 
    try { 
     Session sess = ExtLibUtil.getCurrentSession(); 
     wDb = sess.getDatabase(sess.getServerName(), this.dbname1); 
     wView = wDb.getView(this.viewname1); 
     wDoc = wView.getDocumentByKey(configKey, true); 
     this.debug("Got a doc for key: [" + configKey + "]"); 
     result = wDoc.getItemValue(itemName); 
    } catch (NotesException ne) { 
     if (this.DispLookupErrors) 
      ne.printStackTrace(); 
     this.lastErrorMsg = ne.text; 
     this.debug(this.lastErrorMsg, "error"); 
    } finally { 
     incinerate(wDoc, wView, wDb); 
    } 
    return result; 
} 

Istnieje kilka rzeczy, o powyższym tym zasług wyjaśnienie:

  • Zwykle w języku Java deklarujemy zmienne przy pierwszym użyciu, a nie w stylu spisu treści. Ale z obiektami Domino najlepiej jest wrócić do TOC, aby, niezależnie od tego, czy został zgłoszony wyjątek, możemy próbować je odtworzyć, kiedy skończymy ... stąd użycie w końcu.
  • Obiekt powrotu (który powinien być wartością przedmiotu, a nie sam dokument) również jest deklarowany w TOC, więc możemy zwrócić ten obiekt na końcu metody - ponownie, niezależnie od tego, czy wystąpił wyjątek (jeśli był wyjątek, prawdopodobnie nadal będzie nieważny).
  • W tym przykładzie wywoływana jest metoda narzędzia, która umożliwia przekazanie wszystkich obiektów Domino do pojedynczego wywołania metody w celu przetworzenia.

Oto kod tej metody użytkowego:

private void incinerate(Object... dominoObjects) { 
    for (Object dominoObject : dominoObjects) { 
     if (null != dominoObject) { 
      if (dominoObject instanceof Base) { 
       try { 
        ((Base)dominoObject).recycle(); 
       } catch (NotesException recycleSucks) { 
        // optionally log exception 
       } 
      } 
     } 
    } 
} 

To prywatny, jak jestem przy założeniu, to po prostu zdefiniować go w tej samej fasoli, ale ostatnio staram się określić to jako społeczeństwa statyczna metoda klasy Util, pozwalająca mi na podążanie tym samym wzorcem z praktycznie dowolnego miejsca.

Ostatnia uwaga: jeśli pobierzesz wiele wartości pozycji z dokumentu konfiguracyjnego, byłoby oczywiście drogie ustanowienie nowej bazy danych, widoku i uchwytu dokumentu dla każdej wartości pozycji, którą chcesz zwrócić.Dlatego też zalecam nadpisanie tej metody, aby zaakceptować listę nazw pozycji i zwrócić łańcuch wartości Map <, wynik > z wartości wynikowych. W ten sposób można ustalić pojedynczy uchwyt dla bazy danych, widoku i dokumentu, pobrać wszystkie potrzebne wartości, a następnie poddać obiekty Domino recyklingowi, zanim faktycznie skorzystają z zwracanych wartości produktu.

+0

Tim, jak zwykle idziesz do człowieka w tej technologii. Dziękujemy za doskonałość i kompletność tej odpowiedzi. Bardzo, bardzo pomocny./Newbs – Newbs

+0

Moja przyjemność. Cieszę się, że uznałeś to za przydatne. –

+0

Bieżąca baza danych nie powinna być poddawana recyklingowi, ponieważ dowolny widok lub inne obiekty podrzędne zostaną usunięte z kodu wywołującego. To samo dotyczy oczywiście wszystkich obiektów Domino. Jeśli zdarzy ci się, że obiekt View wskazuje na ten sam widok podczas wywoływania kodu wywołującego, widok ten również niszczy ten obiekt widoku. W większości przypadków wystarczy zrezygnować z aktualnej bazy danych i sesji. –

0

Oto pomysł, z którym eksperymentuję. odpowiedź Tima jest doskonałe, jednak dla mnie naprawdę potrzebny dokument do innych celów, więc próbowałem to ..

Document doc = null; 
      View view = null; 
      try { 
       Database database = ExtLibUtil.getCurrentSessionAsSigner().getCurrentDatabase(); 
       view = database.getView("LocationsByLocationCode"); 
       doc = view.getDocumentByKey(code, true); 
       //need to get this via the db object directly so we can safely recycle the view 
       String id = doc.getNoteID(); 
       doc.recycle(); 
       doc = database.getDocumentByID(id); 

      } catch (Exception e) { 
       log.error(e); 
      } finally { 
       JSFUtils.incinerate(view); 
      } 
      return doc; 

Następnie trzeba upewnić się, że recykling obiekt doc bezpiecznie w jakikolwiek sposób nazywa to jeden

+0

Naprawdę powinieneś użyć [API OpenNTF Domino] (http://www.openntf.org/main.nsf/project.xsp?r=project/OpenNTF%20Domino%20API), jeśli możesz, ponieważ to wszystko załatwi dla ty ;-) ... musisz jednak być na 9.0.x. I właściwie - w twoim obecnym przykładzie nie widzę, abyś coś zyskał? Zwolniłeś uchwyt i użyłeś nowego zaraz po? –

+0

Tak, używam ODA w 9 środowiskach, ale nadal muszę używać 8.53 dla niektórych klientów :( W moim przykładzie uchwyt drugiego dokumentu nie jest dzieckiem widoku, więc widok może być bezpiecznie poddany recyklingowi. martwić się o recykling obiektu db, ponieważ jest on pobierany przez ExtLibUtils –

+0

Wiem, że ktoś (Paul Withers, myślę - lub on będzie wiedział) ma "przeniesiony" ODA do wersji 8.5.3. Prawdopodobnie nie jest to najnowsza wersja - ale nadal da ty magia recyklingu. Może warto spróbować? ;-) –

Powiązane problemy