Jakie są najczęstsze błędy i anty-wzorce, które popełniają programiści NHibernate?

28

Jakie są najczęstsze błędy i anty-wzorce, które popełniają programiści NHibernate? Wyjaśnij, dlaczego są to złe praktyki lub podaj link do zasobów do dalszego czytania.

Na przykład:

  • Jednym z anty-wzorów wspólnych dla nowych programistów NHibernate jest stosowanie identyfikatorów / natywnych POID zamiast jednostek w stylu ORM. Przeczytaj więcej tutaj ...
Darius Kucinskas
źródło
1
Oto niektóre z typowych błędów: Alarmy
1
Jest też kilka cennych postów na temat pułapek NHibernate

Odpowiedzi:

34

Moje osobiste „często wyjaśniane” problemy:

Anty-Wzory

Mieszanie z odłączonymi obiektami (SaveOrUpdate lub Merge plus trochę niechlujnego kodu) zamiast korzystania z DTO. Im bardziej złożone są byty, tym bardziej skomplikowany jest kod. (Oznacza to również, że działa całkiem dobrze z trywialnymi bytami.) Ayende nazywa to również Wzorem Strippera i wyjaśnia problem enkapsulacji.

Niezrozumienie uporczywej ignorancji i pisanie aplikacji NH, jak w przypadku jawnego SQL. Objaw: wywołanie aktualizacji po zmianie obiektu, zastanawianie się, dlaczego zmiany są utrzymywane, nawet jeśli aktualizacja nie została wywołana, zastanawianie się, jak uniknąć zmian, które należy utrwalić.

Niezrozumienie transakcji i wzorca jednostki pracy . Częste anty-wzorce: transakcje niejawne, sesja na operację i sesja na aplikację. Trochę więcej czytania:

Wykorzystanie zdarzeń NH do wprowadzenia logiki aplikacji (np. Śledzenie zmian we wyzwalaczach wstawiania i aktualizacji)

Utwórz jedną klasę na tabelę . Niektórzy ludzie nie rozumieją OOD, inni nie rozumieją projektowania relacyjnego.

Błędy

użycie jeden do jednego zamiast wielu do jednego. Próbowałem to wyjaśnić w tej odpowiedzi .

Korzystanie z funkcji pobierania sprzężenia w połączeniu z SetMaxResult. Moje najnowsze odpowiedzi związane z tym tematem:

Pisanie jednostek zmieniających się . Gdy jednostka nie zwraca dokładnie wartości ustawionej przez NH, jest uważana za brudną i aktualizowana w każdej sesji. Na przykład: zastąpienie trwałej kolekcji NH w ustawieniach właściwości.

  IList<Address> Addresses
  {
    get { return addresses; }
    // will cause the addresses collection to be built up from scratch
    // in the database in every session, even when just reading the entity.
    set { addresses = new List<Address>(value); }
  }

  int Whatever
  {
    // will make the entity dirty after reading negative values from the db.
    // this causes unexpected updates after just reading the entity.
    get { if (whatever < 0) return 0; }
    set { whatever = value; }
  }

Może być więcej, następuje.

Stefan Steinegger
źródło
2
+1: Do listy imho należy dodać „Nieużywany wzorzec jednostki pracy” i „Jedna sesja na aplikację”.
Falcon,
@ Falcon: prawdopodobnie tak. Jest to ogólny problem „niezrozumienia transakcji”. Jednostka pracy jest nieco objęta uporczywą ignorancją. Mimo że są to zupełnie inne koncepcje, powstają te same wzorce.
Stefan Steinegger,
5

Wybierz problem N + 1 ”.

Tutaj kończy się wykonywanie wyboru A dla każdego obiektu, którym chcesz manipulować (N), i wyboru, aby uzyskać listę podmiotów (+1), zamiast pojedynczego wyboru wszystkich obiektów i ich atrybutów.

Sean McMillan
źródło
1
  • Za dużo abstrakcji
  • Nieużywanie mapowań automatycznych z FluentNHibernate
Chytry
źródło
Pierwszy punkt jest trochę niejasny, ale w przypadku, gdy masz na myśli głupie pojęcia, takie jak ukrywanie ISession za „Repozytorium” lub „DAO”, zgadzam się.
Chris
1
Drugi punkt to jednak bzdury. Istnieją dobre powody, dla których często chcemy mieć precyzyjną kontrolę nad fizycznym modelem danych i być w stanie oddzielić go od modelu domeny. W końcu taki jest punkt „M” w „ORM”. Używanie automatycznych mapowań (choć przydatne w prostych scenariuszach) to pokonuje. Poza tym istnieje również problem starszych schematów baz danych integracji, dla których automatyczne mapowanie jest bezużyteczne.
Chris
Korzystam z wbudowanego mapowania opartego na konwencji kodu. Poradzi sobie z wielką bzdurą, którą w innym przypadku musiałbym powtórzyć. Nadal jednak zapewnia swobodę dostosowywania specyficznych elementów, które są warstwami mapowania generowanego przez konwencję. To bardzo pomocne.
Sam
1

Próbuję to wyodrębnić, aby później móc przejść do Entity Framework (lub czegoś innego).

Jest to o wiele, znacznie trudniejsze niż większość ludzi, którzy próbują to zrozumieć. Istnieje wiele różnic między nimi, które mogą cię potknąć w sposób, który czasami może być dość subtelny. Jest to również bardzo rzadkie, aby w końcu było potrzebne - do tego stopnia, że ​​możesz skrupulatnie próbować wdrożyć go przez lata, zanim odkryjesz, że twoje podejście jest błędne.

Ponadto ogranicza korzystanie z całej gamy przydatnych i ważnych funkcji NHibernate, takich jak buforowanie drugiego poziomu, przechwytywanie, zarządzanie współbieżnością, śledzenie zmian, zapytania z wyprzedzeniem i tak dalej.

Gdyby naprawdę istniała uzasadniona potrzeba przełączania między NHibernate a Entity Framework, byłby aktywnie rozwijany projekt wspierający to na GitHub (być może coś podobnego do CommonServiceLocator) z wieloma współautorami i prośbami ściągania.

jammycakes
źródło