2. – studium przypadku
2.1. Problem
Wróćmy do aplikacji, którą chcemy stworzyć. Wychodzimy od istniejącej aplikacji o następującej architekturze:
![]() |
Dla tych, którzy chcą dowiedzieć się więcej na temat:
- NHibernate: Wprowadzenie do ORM Nhibernate [Wprowadzenie do frameworka NHibernate dla platformy .NET (2011)];
- aplikacji ASP.NET (WebForms) z wykorzystaniem NHibernate i Spring: Tworzenie trójwarstwowej aplikacji internetowej z wykorzystaniem ASP.NET, Spring.NET, NHibernate i [Tworzenie trójwarstwowej aplikacji internetowej przy użyciu ASP.NET 2.0, C#, Spring.NET i NHibernate (2010)].
Chcemy przekształcić poprzednią aplikację w tę:
![]() |
gdzie EF5 zastąpiło NHibernate. Ta aplikacja stanowi pretekst do zbadania warstwy EF5. Ponieważ warstwa Spring.NET pozwala nam łatwo zmieniać warstwy bez powodowania błędów, aplikacja 2 będzie korzystać z tej samej warstwy [ASP.NET], co aplikacja 1. Ponieważ niniejszy dokument poświęcony jest EF5, nie będziemy wyjaśniać sposobu tworzenia tej warstwy. Wprowadzimy ją do aplikacji 2, aby sprawdzić, czy działa. Wyjaśnimy jedynie zmiany, jakie należy wprowadzić w pliku konfiguracyjnym Spring.NET.
Przykładowy przypadek wygląda następująco. Chcemy zaoferować lekarzom usługę umawiania wizyt działającą na następującej zasadzie:
- sekretariat zajmuje się przyjmowaniem RV dla dużej liczby lekarzy. Obsługę tę może zapewnić nawet jedna osoba. Jej wynagrodzenie jest dzielone między wszystkich lekarzy korzystających z usługi RV;
- sekretariat i wszyscy lekarze mają dostęp do Internetu;
- rezerwacje RV są zapisywane w scentralizowanej bazie danych, dostępnej przez Internet zarówno dla sekretariatu, jak i dla lekarzy;
- Rezerwacja terminów RV jest zazwyczaj dokonywana przez sekretariat. Może być również dokonywana przez samych lekarzy. Dzieje się tak zwłaszcza wtedy, gdy pod koniec wizyty lekarz sam wyznacza pacjentowi nowy termin RV.
Struktura usługi generowania kodu RV jest następująca:
![]() |
Lekarze zyskują na wydajności, jeśli nie muszą już zajmować się RV. Jeśli będzie ich wystarczająco dużo, ich wkład w koszty funkcjonowania sekretariatu będzie niewielki. Aplikację nazwiemy [RdvMedecins]. Poniżej przedstawiamy zrzuty ekranu pokazujące jej działanie.
Strona główna aplikacji wygląda następująco:

Z tej pierwszej strony użytkownik (sekretariat, lekarz) będzie mógł wykonać szereg czynności. Przedstawiamy je poniżej. Widok po lewej stronie przedstawia ekran, z którego użytkownik składa wniosek, a widok po prawej stronie – odpowiedź wysłaną przez serwer.
![]() |
![]() |
![]() |
![]() |
![]() |
2.2. Baza danych
Baza danych wykorzystywana przez aplikację NHibernate to baza danych MySQL5 zawierająca cztery tabele:

Będzie ona dla nas punktem odniesienia przy tworzeniu wszystkich naszych baz danych.
2.2.1. Tabela [MEDECINS]
Zawiera informacje o lekarzach obsługiwanych przez aplikację [RdvMedecins].
![]() | ![]() |
- ID: numer identyfikacyjny lekarza – klucz główny tabeli
- VERSION: numer identyfikujący wersję wiersza w tabeli. Liczba ta jest zwiększana o 1 za każdym razem, gdy wprowadzana jest zmiana w wierszu.
- NOM: nazwisko lekarza
- PRENOM: jego imię
- TITRE: jego tytuł (panna, pani, pan)
2.2.2. Tabela [CLIENTS]
Pacjenci poszczególnych lekarzy są zapisani w tabeli [CLIENTS]:
![]() | ![]() |
- ID: numer identyfikacyjny pacjenta – klucz główny tabeli
- VERSION: numer identyfikujący wersję wiersza w tabeli. Liczba ta jest zwiększana o 1 za każdym razem, gdy wprowadzana jest zmiana w wierszu.
- NOM: nazwisko klienta
- PRENOM: imię klienta
- TITRE: tytuł (panna, pani, pan)
2.2.3. Tabela [CRENEAUX]
Zawiera listę przedziałów czasowych, w których możliwe jest użycie RV:
![]() |
![]() |
- ID: numer identyfikujący przedział czasowy – klucz główny tabeli
- VERSION: numer identyfikujący wersję wiersza w tabeli. Liczba ta jest zwiększana o 1 za każdym razem, gdy wprowadzana jest zmiana w wierszu.
- ID_MEDECIN: numer identyfikujący lekarza, do którego należy ten przedział czasowy – klucz obcy w kolumnie MEDECINS(ID).
- HDEBUT: godzina rozpoczęcia terminu
- MDEBUT: minuty początku przedziału czasowego
- HFIN: godzina zakończenia przedziału czasowego
- MFIN: minuty zakończenia przedziału czasowego
Drugi wiersz tabeli [CRENEAUX] (por. [1] powyżej) wskazuje na przykład, że przedział nr 2 rozpoczyna się o godz. 8:20 i kończy o godz. 8:40 oraz należy do lekarza nr 1 (pani Marie PELISSIER).
2.2.4. Tabela [RV]
Zawiera listę RV przypisanych każdemu lekarzowi:
![]() |
- ID: numer jednoznacznie identyfikujący RV – klucz główny
- JOUR: dzień, w którym wystawiono RV
- ID_CRENEAU: przedział czasowy dla RV – klucz obcy w kolumnie [ID] tabeli [CRENEAUX] – określa zarówno przedział czasowy, jak i danego lekarza.
- ID_CLIENT: numer klienta, dla którego dokonano rezerwacji – klucz obcy w kolumnie [ID] tabeli [CLIENTS]
Ta tabela posiada , która wymusza unikalność wartości w połączonych kolumnach (JOUR, ID_CRENEAU):
Jeśli wiersz w tabeli [RV] ma wartość (JOUR1, ID_CRENEAU1) w kolumnach (JOUR, ID_CRENEAU), to ta wartość nie może występować nigdzie indziej. W przeciwnym razie oznaczałoby to, że dwa rekordy o wartości RV zostały zarejestrowane w tym samym czasie dla tego samego lekarza. Z punktu widzenia programowania w Javie sterownik bazy danych o wartości JDBC uruchamia sterownik o wartości SQLException, gdy wystąpi taka sytuacja.
Wiersz id o wartości 7 (por. [1] powyżej) oznacza, że rezerwacja RV została dokonana na przedział czasowy nr 10 dla klienta nr 2 w dniu 10.09.2006 r. Z tabeli [CRENEAUX] wynika, że termin nr 10 odpowiada przedziałowi czasowemu 11:00–11:20 i należy do lekarza nr 1 (pani Marie PELISSIER). Z tabeli [CLIENTS] wynika, że klient nr 2 to pani Christine GERMAN.
Niniejszy studium przypadku stał się tematem artykułu Java [http://tahe.developpez.com/java/primefaces], w którym wykorzystano bibliotekę Hibernate dla Javy ORM.














