Dane szczegółowe książki
Hibernate w akcji: popraw wydajność aplikacji bazodanowych w Javie / Bauer, Christian.; King, Gavin; Jońca, Rafał
Tytuł
Hibernate w akcji: popraw wydajność aplikacji bazodanowych w Javie
Tytuł oryginału
Hibernate in action
Wydawnictwo
Gliwice: "Helion", 2007
ISBN
9788324605279
Hasła przedmiotowe
Informacje dodatkowe
Książka zawiera pliki z przykładami
Spis treści
pokaż spis treści
Przedmowa 9
Wstęp 11
Podziękowania 13
O książce i autorach 15
O Hibernate 3 i EJB 3 19
1. Trwałość dzięki odwzorowaniu obiektowo-relacyjnemu 21
1.1. Czym jest trwałość? 23
1.1.1. Relacyjne bazy danych 23
1.1.2. Język SQL 24
1.1.3. Korzystanie z SQL w Javie 24
1.1.4. Trwałość w aplikacjach obiektowych 25
1.2. Niedopasowanie paradygmatów 27
1.2.1. Problem szczegółowości 28
1.2.2. Problem podtypów 29
1.2.3. Problem identyczności 30
1.2.4. Problemy dotyczące asocjacji 32
1.2.5. Problem nawigacji po grafie obiektów 33
1.2.6. Koszt niedopasowania 34
1.3. Warstwy trwałości i alternatywy 35
1.3.1. Architektura warstwowa 35
1.3.2. Ręczne tworzenie warstwy trwałości za pomocą SQL i JDBC 37
1.3.3. Wykorzystanie serializacji 38
1.3.4. A może ziarenka encyjne EJB? 39
Spis treści
1.3.5. Obiektowe systemy bazodanowe 40
1.3.6. Inne rozwiązania 41
1.4. Odwzorowanie obiektowo-relacyjne 41
1.4.1. Czym jest ORM? 42
1.4.2. Ogólne problemy ORM 44
1.4.3. Dlaczego ORM? 45
1.5. Podsumowanie 47
2. Wprowadzenie i integracja Hibernate 49
2.1. „Witaj świecie" w stylu Hibernate 50
2.2. Podstawy architektury Hibernate 55
2.2.1. Interfejsy podstawowe 56
2.2.2. Interfejsy wywołań zwrotnych 58
2.2.3. Typy 58
2.2.4. Interfejsy rozszerzeń 59
2.3. Konfiguracja podstawowa 59
2.3.1. Tworzenie obiektu SessionFactory 60
2.3.2. Konfiguracja w środowisku niezarządzanym 62
2.3.3. Konfiguracja w środowisku zarządzanym 66
2.4. Zaawansowane ustawienia konfiguracyjne 68
2.4.1. Konfiguracja bazująca na pliku XML 69
2.4.2. Obiekt SessionFactory dowiązany do JNDI 70
2.4.3. Dzienniki 71
2.4.4. Java Management Extensions 73
2.5. Podsumowanie 75
3. Odwzorowanie klas trwałości danych 77
3.1. Aplikacja CaveatEmptor 78
3.1.1. Analiza dziedziny biznesowej 79
3.1.2. Model dziedzinowy CaveatEmptor 79
3.2. Implementacja modelu dziedzinowego 82
3.2.1. Kwestia przesiąkania zadań 82
3.2.2. Trwałość automatyczna i przezroczysta 83
3.2.3. Tworzenie klas POJO 84
3.2.4. Implementacja asocjacji POJO 86
3.2.5. Dodanie logiki do metod dostępowych 90
3.3. Definicja metadanych odwzorowujących 92
3.3.1. MetadanewplikuXML 92
3.3.2. Podstawowe odwzorowania właściwości i klas 95
3.3.3. Programowanie zorientowane na atrybuty 101
3.3.4. Modyfikacja metadanych w trakcie działania aplikacji 102
3.4. Identyczność obiektów 104
3.4.1. Identyczność a równość 104
3.4.2. Tożsamość bazodanowa w Hibernate 104
3.4.3. Wybór kluczy głównych 106
3.5. Szczegółowe modele obiektów 108
3.5.1. Encje i typy wartości 109
3.5.2. Stosowanie komponentów 109
3.6. Odwzorowanie dziedziczenia klas 113
3.6.1. Tabela na klasę konkretną 113
3.6.2. Tabela na każdą hierarchię klas 115
Spis treści
3.6.3. Tabela na każdą podklasę 117
3.6.4. Wybór strategii 120
3.7. Asocjacje 121
3.7.1. Asocjacje zarządzane? 121
3.7.2. Krotność 122
3.7.3. Najprostsza możliwa asocjacja 122
3.7.4. Tworzenie asocjacji dwukierunkowej 123
3.7.5. Związek rodzic-potomek 126
3.8. Podsumowanie 127
4. Stosowanie obiektów trwałych 129
4.1. Cykl życia obiektu trwałego 130
4.1.1. Obiekty ulotne 131
4.1.2. Obiekty trwałe 132
4.1.3. Obiekt odłączony 133
4.1.4. Zasięg identyczności obiektów 134
4.1.5. Poza zasięgiem identyczności 135
4.1.6. Implementacja equals() i hashCode() 136
4.2. Zarządca trwałości 140
4.2.1. Czynienie obiektu trwałym 140
4.2.2. Aktualizacja stanu trwałego obiektu odłączonego 141
4.2.3. Pobranie obiektu trwałego 142
4.2.4. Aktualizacja obiektu trwałego 143
4.2.5. Zmiana obiektu trwałego na ulotny 143
4.2.6. Zmiana obiektu odłączonego na ulotny 144
4.3. Trwałość przechodnia w Hibernate 144
4.3.1. Przechodniość przez osiągalność 145
4.3.2. Trwałość kaskadowa w Hibernate 146
4.3.3. Zarządzanie kategoriami przedmiotów 147
4.3.4. Rozróżnienie obiektów ulotnych i odłączonych 151
4.4. Pobieranie obiektów 152
4.4.1. Pobieranie obiektów na podstawie identyfikatora 153
4.4.2. Wprowadzenie do HQL 154
4.4.3. Zapytania przez określenie kryteriów 155
4.4.4. Zapytanie przez przykład 155
4.4.5. Strategie sprowadzania danych 156
4.4.6. Wybór strategii sprowadzania w odwzorowaniach 158
4.4.7. Optymalizacja pobierania obiektów 163
4.5. Podsumowanie 164
5. Transakcje, współbieżność i buforowanie 167
5.1. Transakcje bazodanowe 169
5.1.1. Transakcje JDBC i JTA 170
5.1.2. Interfejs Transaction 171
5.1.3. Opróżnianie sesji 173
5.1.4. Poziomy izolacji 174
5.1.5. Wybór poziomu izolacji 176
5.1.6. Ustawianie poziomu izolacji 177
5.1.7. Blokada pesymistyczna , 177
5.2. Transakcje aplikacyjne 180
5.2.1. Wersjonowanie zarządzane 181
Spis treści
5.2.2. Szczegółowość sesji 184
5.2.3. Inne sposoby implementacji blokady optymistycznej 185
5.3. Buforowanie — teoria i praktyka 186
5.3.1. Strategie i zasięgi buforowania 187
5.3.2. Architektura buforów Hibernate 190
5.3.3. Buforowanie w praktyce 195
5.4. Podsumowanie 204
6. Zaawansowane zagadnienia odwzorowań 205
6.1. System typów Hibernate 206
6.1.1. Wbudowane typy odwzorowań 207
6.1.2. Zastosowania typów odwzorowań 210
6.2. Odwzorowywanie kolekcji typów wartości 220
6.2.1. Zbiory, pojemniki, listy i odwzorowania 220
6.3. Odwzorowanie asocjacji encyjnych 228
6.3.1. Asocjacja jeden-do-jednego 229
6.3.2. Asocjacje wiele-do-wielu 232
6.4. Odwzorowanie asocjacji polimorficznych 241
6.4.1. Polimorficzna asocjacja wiele-do-jednego 241
6.4.2. Kolekcje polimorficzne 243
6.4.3. Asocjacje polimorficzne i jedna tabela na klasę konkretną 244
6.5. Podsumowanie 246
7. Wydajne pobieranie obiektów 247
7.1. Wykonywanie zapytań 249
7.1.1. Interfejsy zapytań 249
7.1.2. Dowiązywanie parametrów 251
7.1.3. Zapytania nazwane 254
7.2. Proste zapytania dotyczące obiektów 255
7.2.1. Najprostsze zapytanie 256
7.2.2. Zastosowanie aliasów 256
7.2.3. Zapytania polimorficzne 257
7.2.4. Ograniczenia 257
7.2.5. Operatory porównań 258
7.2.6. Dopasowywanie tekstów 260
7.2.7. Operatory logiczne 261
7.2.8. Kolejność wyników zapytań 262
7.3. Złączanie asocjacji 262
7.3.1. Złączenia w Hibernate 264
7.3.2. Pobieranie asocjacji 265
7.3.3. Aliasy i złączenia 266
7.3.4. Złączenia niejawne 270
7.3.5. Złączenia w stylu theta 271
7.3.6. Porównywanie identyfikatorów 272
7.4. Tworzenie zapytań raportujących 273
7.4.1. Projekcja 274
7.4.2. Agregacja 276
7.4.3. Grupowanie 277
7.4.4. Ograniczanie grup klauzulą having 278
7.4.5. Poprawa wydajności zapytań raportujących 279
Spis treści
7.5. Techniki tworzenia zaawansowanych zapytań 279
7.5.1. Zapytania dynamiczne 280
7.5.2. Filtry kolekcji 282
7.5.3. Podzapytania 284
7.5.4. Zapytania SQL 286
7.6. Optymalizacja pobierania obiektów 288
7.6.1. Rozwiązanie problemu n+1 pobrań danych 288
7.6.2. Zapytania iterate() 291
7.6.3. Buforowanie zapytań 292
7.7. Podsumowanie 294
8. Tworzenie aplikacji stosujących Hibernate 295
8.1. Projektowanie aplikacji warstwowych 296
8.1.1. Użycie Hibernate w systemie serwletowym 297
8.1.2. Stosowanie Hibernate w kontenerze EJB 311
8.2. Implementacja transakcji aplikacyjnych 319
8.2.2. Trudny sposób 321
8.2.3. Odłączone obiekty trwałe 322
8.2.4. Długa sesja 323
8.2.5. Wybór odpowiedniej implementacji transakcji aplikacyjnych 327
8.3. Obsługa specjalnych rodzajów danych 328
8.3.1. Starsze schematy baz danych i klucze złożone 328
8.3.2. Dziennik audytowy 337
8.4. Podsumowanie 343
9. Narzędzia Hibernate 345
9.1. Procesy tworzenia aplikacji 346
9.1.1. Podejście z góry na dół 347
9.1.2. Podejście z dołu do góry 347
9.1.3. Podejście od środka 347
9.1.4. Spotkanie w środku 347
9.1.5. Ścieżka przejścia 348
9.2. Automatyczne generowanie schematu bazy danych 348
9.2.1. Przygotowanie metadanych odwzorowania 349
9.2.2. Utworzenie schematu 351
9.2.3. Aktualizacja schematu bazy danych 353
9.3. Generowanie kodu klas POJO 354
9.3.1. Wprowadzenie metaatrybutów 355
9.3.2. Metody odnajdujące 357
9.3.3. Konfiguracja hbm2java 358
9.3.4. Uruchamianie narzędzia hbm2java 359
9.4. Istniejące schematy i Middlegen 360
9.4.1. Uruchomienie Middlegen 360
9.4.2. Ograniczanie tabel i związków 362
9.4.3. Dostosowanie generowania metadanych 363
9.4.4. Generowanie metadanych hbm2java i XDoclet 365
9.5. XDoclet 366
9.5.1. Ustawianie atrybutów typu wartości 367
9.5.2. Odwzorowanie asocjacji encyjnych 368
9.5.3. Uruchomienie XDoclet 369
9.6. Podsumowanie 371
Spis treści
A Podstawy języka SQL 373
B Strategie implementacji systemów ORM 377
B.l. Właściwości czy pola? 378
B.2. Strategie sprawdzania zabrudzenia 379
B.2.1. Dziedziczenie po wygenerowanym kodzie 379
B.2.2. Przetwarzanie kodu źródłowego 379
B.2.3. Przetwarzanie kodu bajtowego 380
B.2.4. Introspekcja 380
B.2.5. Generowanie kodu bajtowego „w locie" 381
B.2.6. Obiekty „uogólnione" 382
C Powrót do świata rzeczywistego 383
Cl. Dziwna kopia 384
C.2. Im więcej, tym lepiej 385
C.3. Nie potrzebujemy kluczy głównych 385
C.4. Czas nie jest liniowy 386
C.5. Dynamicznie niebezpieczne 386
C.6. Synchronizować czy nie synchronizować? 387
C.7. Naprawdę gruby klient 388
C.8. Wznawianie Hibernate 388
Bibliografia 391
Skorowidz 393
Wstęp 11
Podziękowania 13
O książce i autorach 15
O Hibernate 3 i EJB 3 19
1. Trwałość dzięki odwzorowaniu obiektowo-relacyjnemu 21
1.1. Czym jest trwałość? 23
1.1.1. Relacyjne bazy danych 23
1.1.2. Język SQL 24
1.1.3. Korzystanie z SQL w Javie 24
1.1.4. Trwałość w aplikacjach obiektowych 25
1.2. Niedopasowanie paradygmatów 27
1.2.1. Problem szczegółowości 28
1.2.2. Problem podtypów 29
1.2.3. Problem identyczności 30
1.2.4. Problemy dotyczące asocjacji 32
1.2.5. Problem nawigacji po grafie obiektów 33
1.2.6. Koszt niedopasowania 34
1.3. Warstwy trwałości i alternatywy 35
1.3.1. Architektura warstwowa 35
1.3.2. Ręczne tworzenie warstwy trwałości za pomocą SQL i JDBC 37
1.3.3. Wykorzystanie serializacji 38
1.3.4. A może ziarenka encyjne EJB? 39
Spis treści
1.3.5. Obiektowe systemy bazodanowe 40
1.3.6. Inne rozwiązania 41
1.4. Odwzorowanie obiektowo-relacyjne 41
1.4.1. Czym jest ORM? 42
1.4.2. Ogólne problemy ORM 44
1.4.3. Dlaczego ORM? 45
1.5. Podsumowanie 47
2. Wprowadzenie i integracja Hibernate 49
2.1. „Witaj świecie" w stylu Hibernate 50
2.2. Podstawy architektury Hibernate 55
2.2.1. Interfejsy podstawowe 56
2.2.2. Interfejsy wywołań zwrotnych 58
2.2.3. Typy 58
2.2.4. Interfejsy rozszerzeń 59
2.3. Konfiguracja podstawowa 59
2.3.1. Tworzenie obiektu SessionFactory 60
2.3.2. Konfiguracja w środowisku niezarządzanym 62
2.3.3. Konfiguracja w środowisku zarządzanym 66
2.4. Zaawansowane ustawienia konfiguracyjne 68
2.4.1. Konfiguracja bazująca na pliku XML 69
2.4.2. Obiekt SessionFactory dowiązany do JNDI 70
2.4.3. Dzienniki 71
2.4.4. Java Management Extensions 73
2.5. Podsumowanie 75
3. Odwzorowanie klas trwałości danych 77
3.1. Aplikacja CaveatEmptor 78
3.1.1. Analiza dziedziny biznesowej 79
3.1.2. Model dziedzinowy CaveatEmptor 79
3.2. Implementacja modelu dziedzinowego 82
3.2.1. Kwestia przesiąkania zadań 82
3.2.2. Trwałość automatyczna i przezroczysta 83
3.2.3. Tworzenie klas POJO 84
3.2.4. Implementacja asocjacji POJO 86
3.2.5. Dodanie logiki do metod dostępowych 90
3.3. Definicja metadanych odwzorowujących 92
3.3.1. MetadanewplikuXML 92
3.3.2. Podstawowe odwzorowania właściwości i klas 95
3.3.3. Programowanie zorientowane na atrybuty 101
3.3.4. Modyfikacja metadanych w trakcie działania aplikacji 102
3.4. Identyczność obiektów 104
3.4.1. Identyczność a równość 104
3.4.2. Tożsamość bazodanowa w Hibernate 104
3.4.3. Wybór kluczy głównych 106
3.5. Szczegółowe modele obiektów 108
3.5.1. Encje i typy wartości 109
3.5.2. Stosowanie komponentów 109
3.6. Odwzorowanie dziedziczenia klas 113
3.6.1. Tabela na klasę konkretną 113
3.6.2. Tabela na każdą hierarchię klas 115
Spis treści
3.6.3. Tabela na każdą podklasę 117
3.6.4. Wybór strategii 120
3.7. Asocjacje 121
3.7.1. Asocjacje zarządzane? 121
3.7.2. Krotność 122
3.7.3. Najprostsza możliwa asocjacja 122
3.7.4. Tworzenie asocjacji dwukierunkowej 123
3.7.5. Związek rodzic-potomek 126
3.8. Podsumowanie 127
4. Stosowanie obiektów trwałych 129
4.1. Cykl życia obiektu trwałego 130
4.1.1. Obiekty ulotne 131
4.1.2. Obiekty trwałe 132
4.1.3. Obiekt odłączony 133
4.1.4. Zasięg identyczności obiektów 134
4.1.5. Poza zasięgiem identyczności 135
4.1.6. Implementacja equals() i hashCode() 136
4.2. Zarządca trwałości 140
4.2.1. Czynienie obiektu trwałym 140
4.2.2. Aktualizacja stanu trwałego obiektu odłączonego 141
4.2.3. Pobranie obiektu trwałego 142
4.2.4. Aktualizacja obiektu trwałego 143
4.2.5. Zmiana obiektu trwałego na ulotny 143
4.2.6. Zmiana obiektu odłączonego na ulotny 144
4.3. Trwałość przechodnia w Hibernate 144
4.3.1. Przechodniość przez osiągalność 145
4.3.2. Trwałość kaskadowa w Hibernate 146
4.3.3. Zarządzanie kategoriami przedmiotów 147
4.3.4. Rozróżnienie obiektów ulotnych i odłączonych 151
4.4. Pobieranie obiektów 152
4.4.1. Pobieranie obiektów na podstawie identyfikatora 153
4.4.2. Wprowadzenie do HQL 154
4.4.3. Zapytania przez określenie kryteriów 155
4.4.4. Zapytanie przez przykład 155
4.4.5. Strategie sprowadzania danych 156
4.4.6. Wybór strategii sprowadzania w odwzorowaniach 158
4.4.7. Optymalizacja pobierania obiektów 163
4.5. Podsumowanie 164
5. Transakcje, współbieżność i buforowanie 167
5.1. Transakcje bazodanowe 169
5.1.1. Transakcje JDBC i JTA 170
5.1.2. Interfejs Transaction 171
5.1.3. Opróżnianie sesji 173
5.1.4. Poziomy izolacji 174
5.1.5. Wybór poziomu izolacji 176
5.1.6. Ustawianie poziomu izolacji 177
5.1.7. Blokada pesymistyczna , 177
5.2. Transakcje aplikacyjne 180
5.2.1. Wersjonowanie zarządzane 181
Spis treści
5.2.2. Szczegółowość sesji 184
5.2.3. Inne sposoby implementacji blokady optymistycznej 185
5.3. Buforowanie — teoria i praktyka 186
5.3.1. Strategie i zasięgi buforowania 187
5.3.2. Architektura buforów Hibernate 190
5.3.3. Buforowanie w praktyce 195
5.4. Podsumowanie 204
6. Zaawansowane zagadnienia odwzorowań 205
6.1. System typów Hibernate 206
6.1.1. Wbudowane typy odwzorowań 207
6.1.2. Zastosowania typów odwzorowań 210
6.2. Odwzorowywanie kolekcji typów wartości 220
6.2.1. Zbiory, pojemniki, listy i odwzorowania 220
6.3. Odwzorowanie asocjacji encyjnych 228
6.3.1. Asocjacja jeden-do-jednego 229
6.3.2. Asocjacje wiele-do-wielu 232
6.4. Odwzorowanie asocjacji polimorficznych 241
6.4.1. Polimorficzna asocjacja wiele-do-jednego 241
6.4.2. Kolekcje polimorficzne 243
6.4.3. Asocjacje polimorficzne i jedna tabela na klasę konkretną 244
6.5. Podsumowanie 246
7. Wydajne pobieranie obiektów 247
7.1. Wykonywanie zapytań 249
7.1.1. Interfejsy zapytań 249
7.1.2. Dowiązywanie parametrów 251
7.1.3. Zapytania nazwane 254
7.2. Proste zapytania dotyczące obiektów 255
7.2.1. Najprostsze zapytanie 256
7.2.2. Zastosowanie aliasów 256
7.2.3. Zapytania polimorficzne 257
7.2.4. Ograniczenia 257
7.2.5. Operatory porównań 258
7.2.6. Dopasowywanie tekstów 260
7.2.7. Operatory logiczne 261
7.2.8. Kolejność wyników zapytań 262
7.3. Złączanie asocjacji 262
7.3.1. Złączenia w Hibernate 264
7.3.2. Pobieranie asocjacji 265
7.3.3. Aliasy i złączenia 266
7.3.4. Złączenia niejawne 270
7.3.5. Złączenia w stylu theta 271
7.3.6. Porównywanie identyfikatorów 272
7.4. Tworzenie zapytań raportujących 273
7.4.1. Projekcja 274
7.4.2. Agregacja 276
7.4.3. Grupowanie 277
7.4.4. Ograniczanie grup klauzulą having 278
7.4.5. Poprawa wydajności zapytań raportujących 279
Spis treści
7.5. Techniki tworzenia zaawansowanych zapytań 279
7.5.1. Zapytania dynamiczne 280
7.5.2. Filtry kolekcji 282
7.5.3. Podzapytania 284
7.5.4. Zapytania SQL 286
7.6. Optymalizacja pobierania obiektów 288
7.6.1. Rozwiązanie problemu n+1 pobrań danych 288
7.6.2. Zapytania iterate() 291
7.6.3. Buforowanie zapytań 292
7.7. Podsumowanie 294
8. Tworzenie aplikacji stosujących Hibernate 295
8.1. Projektowanie aplikacji warstwowych 296
8.1.1. Użycie Hibernate w systemie serwletowym 297
8.1.2. Stosowanie Hibernate w kontenerze EJB 311
8.2. Implementacja transakcji aplikacyjnych 319
8.2.2. Trudny sposób 321
8.2.3. Odłączone obiekty trwałe 322
8.2.4. Długa sesja 323
8.2.5. Wybór odpowiedniej implementacji transakcji aplikacyjnych 327
8.3. Obsługa specjalnych rodzajów danych 328
8.3.1. Starsze schematy baz danych i klucze złożone 328
8.3.2. Dziennik audytowy 337
8.4. Podsumowanie 343
9. Narzędzia Hibernate 345
9.1. Procesy tworzenia aplikacji 346
9.1.1. Podejście z góry na dół 347
9.1.2. Podejście z dołu do góry 347
9.1.3. Podejście od środka 347
9.1.4. Spotkanie w środku 347
9.1.5. Ścieżka przejścia 348
9.2. Automatyczne generowanie schematu bazy danych 348
9.2.1. Przygotowanie metadanych odwzorowania 349
9.2.2. Utworzenie schematu 351
9.2.3. Aktualizacja schematu bazy danych 353
9.3. Generowanie kodu klas POJO 354
9.3.1. Wprowadzenie metaatrybutów 355
9.3.2. Metody odnajdujące 357
9.3.3. Konfiguracja hbm2java 358
9.3.4. Uruchamianie narzędzia hbm2java 359
9.4. Istniejące schematy i Middlegen 360
9.4.1. Uruchomienie Middlegen 360
9.4.2. Ograniczanie tabel i związków 362
9.4.3. Dostosowanie generowania metadanych 363
9.4.4. Generowanie metadanych hbm2java i XDoclet 365
9.5. XDoclet 366
9.5.1. Ustawianie atrybutów typu wartości 367
9.5.2. Odwzorowanie asocjacji encyjnych 368
9.5.3. Uruchomienie XDoclet 369
9.6. Podsumowanie 371
Spis treści
A Podstawy języka SQL 373
B Strategie implementacji systemów ORM 377
B.l. Właściwości czy pola? 378
B.2. Strategie sprawdzania zabrudzenia 379
B.2.1. Dziedziczenie po wygenerowanym kodzie 379
B.2.2. Przetwarzanie kodu źródłowego 379
B.2.3. Przetwarzanie kodu bajtowego 380
B.2.4. Introspekcja 380
B.2.5. Generowanie kodu bajtowego „w locie" 381
B.2.6. Obiekty „uogólnione" 382
C Powrót do świata rzeczywistego 383
Cl. Dziwna kopia 384
C.2. Im więcej, tym lepiej 385
C.3. Nie potrzebujemy kluczy głównych 385
C.4. Czas nie jest liniowy 386
C.5. Dynamicznie niebezpieczne 386
C.6. Synchronizować czy nie synchronizować? 387
C.7. Naprawdę gruby klient 388
C.8. Wznawianie Hibernate 388
Bibliografia 391
Skorowidz 393