Hibernate Flashcards
Zalety ORM
- Abstrakcja bazy danych: Praca na poziomie obiektów zamiast SQL.
- Niezależność od bazy danych: Ułatwia zmianę systemu baz danych.
- Zwiększona produktywność: Skupienie na logice biznesowej, mniej ręcznego kodu SQL.
- Wsparcie dla skomplikowanych operacji: Dziedziczenie, kompozycja, wielowątkowość.
- Bezpieczeństwo: Ochrona przed atakami typu SQL Injection.
- Optymalizacja wydajności: Pamięć podręczna, leniwe ładowanie, wsparcie dla transakcji.
- Zarządzanie relacjami: Naturalne zarządzanie relacjami obiektów.
- Spójność: Jednolita reprezentacja danych.
Czym jest ORM
ORM, czyli Object-Relational Mapping , to technika programowania, która umożliwia konwersję danych pomiędzy systemami relacyjnymi baz danych a obiektowo zorientowanymi językami programowania.
Czym jest sesja w Hibernate?
- Sesja w Hibernate reprezentuje pojedynczą jednostkę pracy z bazą danych.
- Sesja umożliwia operacje CRUD (tworzenie, odczytzarządzanie transakcjami
- dowolna ilość sesji w aplikacji
- ywanie, aktualizację, usuwanie) na obiektach
- zarządzanie transakcjami
- zapewnia kontekst dla persystencji obiektów.
Czym jest SessionFactory w Hibernate?
- specjalny obiekt, który jest punktem wyjścia do tworzenia aplikacji z hibernate
- odpowiedzialna za tworzenie obiektów Session
- odpowiedzialna za utrzymanie połączenia z bazą danych oraz konfiguracje
- jjedna Session Factory dla każdej bazy danych
- ma cache drugiego poziomu
Najwżniejsze interfejsy w Hibernate
Configuration
SessionFactory
Session
Criteria
Query
Transaction
Czym jest Lazy Loading w kontekście Hibernate?
- Lazy Loading to technika ładowania danych w momencie, gdy są one rzeczywiście potrzebne
- ## obiekty powiązane z głównym obiektem (np. kolekcje) nie są ładowane od razu razem z głównym obiektem, ale dopiero wtedy, gdy próbuje uzyskać do nich dostęp.
Czym jest cache ?
- mechanizmu, który umożliwia przechowywanie obiektów w pamięci między sesjami (transakcjami),
- pozwala na zmniejszenie liczby kosztownych zapytań do bazy danych
Cache piewszego poziomu vs Cache drugiego poziomu
czym jest Hibernate Configuration File
- hibernate.cfg.xml, to podstawowy plik XML używany do konfigurowania Hibernate.
- określenie szczegółów dotyczących połączenia z bazą danych, właściwości dialektu bazy danych oraz innych globalnych ustawień
- umożliwia określenie mapowanych klas lub plików mapowania, które definiują, jak obiekty Java powinny być przechowywane w bazie danych.
Podstawowe elementy hibernate.cfg.xml
- dotyczące sterownika JDBC,
- adresu URL bazy danych,
- nazwy użytkownika, hasła itp.
- wybór dialektu SQL,
- konfiguracja cache 2 poziomu
- format logowania zapytań SQL.
- które klasy są mapowane do tabel w bazie danych.
jak stworzyc klase immutable w hibernate przy pomocy XML?
markingmutable=false
CZYM JEST Hibernate Inheritance Mapping?
- technika mapowania hierarchii dziedziczenia w klasach do struktur table w bazie danych
Jakie są trzy główne strategie mapowania dziedziczenia w Hibernate?
- Table Per Class Hierarchy (Jedna tabela dla całej hierarchii).
- Table Per Concrete Class (Jedna tabela dla każdej konkretnej klasy).
- Table Per Subclass (Jedna tabela dla każdej podklasy).
Opisz strategię “SingleTable Strategy”.
- Wszystkie klasy w hierarchii dziedziczenia są mapowane na** jedną tabelę. **
- Wprowadzenie kolumny dyskryminatora, która określa typ konkretnej instancji.
- Kolumny, które nie są wspólne dla wszystkich podklas, mogą mieć wartość NULL.
Opisz strategię “Table Per Concrete Class”.
- Dla każdej konkretnej klasy w hierarchii dziedziczenia tworzona jest osobna tabela.
- Nie ma potrzeby kolumny dyskryminatora.
- Może to prowadzić do powielenia kolumn w wielu tabelach i konieczności wielokrotnego odwzorowania wspólnych atrybutów w każdej tabeli.
Opisz strategię “Table Per Subclass”.
- Dla każdej klasy w hierarchii dziedziczenia tworzona jest osobna tabela, ale jedynie z atrybutami, które są unikalne dla tej klasy.
- Tablice są połączone za pomocą klucza głównego.
- Eliminuje problem wartości NULL oraz problem dublowania kolumn.
@Entity
Oznacza klasę jako encję, co sprawia, że jest mapowana do tabeli w bazie danych.
Klasy oznaczone tą adnotacją mogą być używane w operacjach CRUD za pomocą sesji Hibernate.
@Table
Umożliwia określenie nazwy tabeli i innych opcji tabeli dla mapowanej encji. Jeśli nie jest używana, nazwa klasy zostanie użyta jako nazwa tabeli.
@JoinTable
Określa tabelę łączącą w relacji wiele-do-wielu. Można w niej określić nazwę tabeli, kolumny łączące itp.
@JoinColumn
Określa nazwę kolumny, której używa się do łączenia w relacjach.
@Transient
Oznacza, że dane pole nie powinno być utrwalane ani mapowane do bazy danych.
@GeneratedValue
Określa strategię generowania wartości dla klucza głównego.
Strategia Squence
Strategia SEQUENCE używa sekwencji bazy danych do generowania kluczy głównych.
Wymaga określenia nazwy sekwencji. Jest to popularne podejście w bazach danych takich jak Oracle.
@Id **@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "my_seq_gen") @SequenceGenerator(name = "my_seq_gen", sequenceName = "MY_SEQ")** private Long id;
Strategia Identity
Strategia IDENTITY polega na pozostawieniu generowania klucza głównego bazie danych, która używa kolumny autoinkrementacyjnej.
Jest to popularne w bazach danych takich jak MySQL czy MS SQL Server.
Strategia table
Strategia TABLE polega na używaniu oddzielnej tabeli w bazie danych do przechowywania wartości klucza głównego dla każdej encji.
Tabela zawiera wartość klucza, który ma być użyty następnie.
@Id @GeneratedValue(strategy = GenerationType.TABLE, generator = "table_gen") @TableGenerator(name = "table_gen", table = "ID_GEN_TABLE", pkColumnName = "GEN_NAME", valueColumnName = "GEN_VAL", pkColumnValue = "NEXT_ID", allocationSize = 1) private Long id;
Co to jest HQL?
- HQL (Hibernate Query Language) zapytań specyficzny dla Hibernate.
- operuje on na obiektach i ich właściwościach zamiast bezpośrednio na tabelach i kolumnach baz danych.
Jakie są główne cechy HQL?
- Operuje na obiektach, nie tabelach.
Jest niezależny od konkretnej bazy danych. - Obsługuje zaawansowane funkcje, takie jak stronicowanie i joiny.
- Obsługuje parametryzowane zapytania.
Jak w HQL odwołuje się do obiektów i ich właściwości?
W HQL odwołania kierowane są do nazw klas (np. “FROM Student”) i ich właściwości (np. “s.age > 18”), a nie bezpośrednio do nazw tabel i kolumn baz danych
Co to jest “transient” w kontekście cyklu życia encji w Hibernate?
- obiekt został stworzony, ale nie jest jeszcze skojarzony z sesją Hibernate
- nie ma reprezentacji w bazie danych.
- Jest to początkowy stan obiektu.
- jeśli nie zapiszemy to utracimy
- gdy aplikacja przestanie się odwoływać bedzie garbage collected
Co oznacza stan “persistent” encji w Hibernate?
- obiekt jest skojarzony z sesją Hibernate
- jest bazie danych
-Wszelkie zmiany w obiekcie będą automatycznie zsynchronizowane z bazą danych, o ile sesja jest otwarta.
Jakie jest znaczenie stanu “detached” dla encji w Hibernate?
- obiekt był wcześniej skojarzony z sesją Hibernate (był w stanie “persistent”), ale sesja została zamknięta. (kontekt utrwalania)
- Obiekt nadal ma identyfikator i może być ponownie załączony do nowej sesji.
Jak przenieść encję z stanu “detached” do “persistent”?
można użyć metod takich jak **merge()
Co się dzieje z encją w stanie “persistent”, gdy sesja Hibernate jest zamykana?
- , obiekt przechodzi ze stanu “persistent” do stanu “detached
- modyfikowany w trakcie życia sesji, te zmiany są zapisywane w bazie danych przed zamknięciem
- Po zamknięciu sesji obiekt w stanie “detached” nadal może być używany, modyfikowany itp. w kodzie aplikacji. Jednakże wszelkie zmiany dokonane w obiekcie w stanie “detached” nie będą miały wpływu na bazę danych, chyba że obiekt ten zostanie ponownie dołączony do nowej sesji (na przykład poprzez użycie metody merge()).
Co to jest problem N+1 w kontekście ORM?
- ORM wykonuje zbyt wiele zapytań do bazy danych podczas ładowania powiązanych obiektów.
Dla jednego głównego zapytania do bazy danych (1) oraz dodatkowych zapytań dla każdego powiązanego obiektu (N), łącznie wykonuje się N+1 zapytań.
- Jest to nieefektywne i może prowadzić do spowolnień w aplikacji.
Jak rozwiązać problem N+1 w Hibernate?
- UżywanieJOIN FETCH w HQL lub kryteriach zapytania.
- Ustawienie strategii ładowania na EAGER dla powiązanych obiektów (chociaż to może prowadzić do innych problemów z wydajnością, jeśli nie jest używane ostrożnie).
- Używanie BatchSize do określenia liczby obiektów ładowanych w jednym zapytaniu.
Przykład N + 1
Jeśli zapytamy o listę użytkowników i dla każdego z nich zapytamy o jego adresy, pojawi się problem N+1.
Jeśli mamy 50 użytkowników w bazie danych, powyższy kod spowoduje wykonanie 51 zapytań do bazy danych:
- Zapytanie, żeby pobrać wszystkich użytkowników (from User).
- Dla każdego użytkownika zostanie wykonane oddzielne zapytanie, aby pobrać jego adresy.
Fetch Type: Eager
- Gdy encja jest ładowana, wszystkie jej powiązane obiekty są ładowane jednocześnie,
- niezależnie od tego, czy są one bezpośrednio używane w danym momencie czy nie.
- hibernate generuje joina
Wady i zalety Eager
Zalety:
Unikanie problemu N+1 w określonych przypadkach.
Dane są od razu dostępne bez konieczności dodatkowego ładowania.
Wady:
Może prowadzić do nadmiernego ładowania danych, które nie są potrzebne, co wpływa na wydajność.
Jeśli dane są zawsze ładowane, nawet gdy nie są potrzebne, może to prowadzić do niepotrzebnego obciążenia systemu.
- problem iloczynu kartezjanskiego
Fetch Type: Lazy
- Gdy encja jest ładowana, jej powiązane obiekty nie są ładowane od razu.
- Zamiast tego są one ładowane dopiero wtedy, gdy są bezpośrednio odwoływane lub używane.
- hibernate robi dodatkowego selecta
Zalety i wady Lazy
Zalety:
Oszczędność zasobów przez unikanie ładowania niepotrzebnych danych.
Poprawa wydajności, ponieważ dane są ładowane na żądanie.
Wady:
Możliwość napotkania problemu N+1, jeśli nie jest właściwie zarządzany.
Potrzeba aktywnej sesji Hibernate do ładowania leniwych obiektów. Jeśli sesja zostanie zamknięta, próba dostępu do niezaładowanego obiektu spowoduje wyjątek LazyInitializationException.
LazyInitializationException
Wyjątek rzucany przez Hibernate, gdy aplikacja próbuje uzyskać dostęp do obiektu zainicjowanego do ładowania leniwego po zamknięciu sesji.
Relacja OneToOne
Relacja OneToOne
Relacja OneToMany / ManyToOne
Relacja między dwoma encjami, gdzie jedna encja może być powiązana z wieloma innymi encjami.
Relacja ManyToMany
Relacja między dwoma encjami, w której wiele encji z jednej strony może być powiązane z wieloma encjami z drugiej strony.
Czym jest transkacja
- Transakcja to sekwencja operacji wykonywanych jako jedna jednostka pracy.
- Jeśli wszystkie operacje są udane, transakcja jest zatwierdzana (commit), co oznacza, że wszystkie zmiany wprowadzone podczas transakcji są trwale zapisywane.
- Jeśli jedna z operacji nie powiedzie się, cała transakcja jest wycofywana (rollback), co oznacza, że żadna z operacji nie zostaje zapisana.
4 własności transkacji ACID
A (Atomicity): Wszystkie operacje w transakcji są traktowane jako jedna atomowa jednostka pracy. Albo wszystkie się udają, albo żadna nie zostaje zrealizowana.
C (Consistency): Baza danych przechodzi z jednego spójnego stanu do drugiego po zakończeniu transakcji.
I (Isolation): Operacje jednej transakcji są izolowane od innych transakcji. Dwie jednoczesne transakcje nie wpływają na siebie nawzajem.
D (Durability): Po zatwierdzeniu transakcji, jej efekty stają się trwałe i nie mogą być usunięte w przypadku awarii systemu.
Jakie wymagania musi spełniać klasa która jest encja ?
Adnotacja @Entity:
publiczny lub chroniony konstruktor bez
argumentowy:
nie może byc final
żadne pole ani metoda nie może być final
Identyfikator (ID):
Gettery i Settery:
Entity Manager w Hibernate
- Entity Manager to interfejs w JPA (Java Persistence API), który dostarcza zestaw operacji CRUD (create, read, update, delete) oraz innych funkcji zarządzania cyklem życia encji.
- Umożliwia również tworzenie zapytań, zarządzanie transakcjami i wiele innych funkcji związanych z persystencją danych.
Named Queries w Hibernate / JPA
- Named Queries, czyli nazwane zapytania, to zapytania, które są definiowane w encji (lub mapie) i są przypisywane do unikalnych nazw.
- Są one sprawdzane pod kątem poprawności składni w momencie uruchamiania aplikacji, co sprawia, że są bardziej wydajne niż dynamicznie tworzone zapytania, ponieważ są kompilowane tylko raz.
Zalety named queries
- Optymalizacja: Zapytanie jest kompilowane raz przy uruchamianiu aplikacji.
- Czytelność: Można centralnie zarządzać zapytaniami w encjach, co ułatwia śledzenie.
- Bezpieczeństwo: Zmniejsza ryzyko ataków typu SQL Injection.
JPQL
- język zapytań podobny do SQLa
- służy do wykonywania operacji na bazie danych
- ma składnie opartą na SQLu
Natywne metody Hibernate
- find
- save
- update
- delete
JPA
Java Persistence API
- api służace do utrwalania danych w relacyjnych bazach danych
- pozwala uniezależnić się od ORMA
Jak pobrać encje przy użyciu Hibernate
Jak wygląda mapowanie relacji one-to-many jednostronnie ?
- wystarczy Lista w encji właściciela relacji
- JoinColumn
- postronie drugiej nic nie trzeba dodawać
Jak wygląda mapowanie relacji one-to-many dwustronne ?
- trzeba pamiętać , że nie ma JOIN COLUMN
- po drugiej stronie realcji Fetch type Eager
Fetch Type Many-to-One
Eager
Fetych type one-to-many
Lazy
Many-to-Many Encja Product z Attributes
Entity Manager vs Session
Session jest specyficzny dla Hibernate i nie jest przeznaczony jako standard dla różnych narzędzi ORM.
EntityManager jest interfejsem JPA i jest zaprojektowany tak, aby mógł być implementowany przez dowolne narzędzie ORM, które przestrzega specyfikacji JPA (Hibernate może być jedną z takich implementacji, ponieważ zapewnia implementację JPA).
Jak rozwiązać problem iloczynu kartezjańskiego
- Dtos
- Distinct
- -lazy loading
Problem iloczynu kartezjanskiego
- załóżmy , że mamy encje Book i Author
- gdzię autor może mieć wiele ksiązek
- wykonujemy zapytanie JPQL
String jpql = "SELECT a FROM Author a JOIN a.books b";
- zapytanie do spowoduje, że auto pojawi się w wyniku tyle razy ile ma ksiązek
- rozwiązanie
~~~
String jpql = “SELECT DISTINCT a FROM Author a JOIN FETCH a.books b”;
~~~
oraz LazyLoading
FetchMode
- określa jak w relacji pobrać powiązane encje
- @Fetch
FetchMode Select
- domyślny
- każda powiązana encja jest pobierane przez dodatkowego selecta
FetchMode JOIN
- generowane jest jedno zapytanie, które zawiera złaczenie tabeli
Fetch SUBSELECT
- generuje SUBSELECTA
- WHERE IN
Do czego służy Entity Graph
- pozwala na określeniu zestawu atrybutów necji, które mają być załadowane z bazy danych w określonej operacji
- celem jest zapewnienie więszkej kontrolii na operacjami ładowania Eager i Lazy
Przykład Entity Graph
W powyższym przykładzie, gdy pobierasz autora, chcesz również załadować jego książki (oraz wydawców tych książek) w jednym zapytaniu, aby uniknąć problemu N+1 w dostępie do bazy danych.
Czym jest Batching?
- to wykonywanie operacji w grupach
- często jest to dzielenie dużej ilości operacji na mniejsze grupki
- W hibernate jest to wysyłanie do bazy danych kilku zapytań tego samego typu w jednej porcji
- np. wykonanie 100 tys zapyań podzielić na mniejsze batche
- tyle zapytań w jednej transkacji jest nibezpieczne
- nie jest właczone domyślnie
- Id nie możę być Identity
Jak wyciścić Sesje Hibernate (Cache możę być out of memory)
EntityManger ma dwie metody:
em.flush();
em.clear();
Hibernate Stronninowanie wyników na przykładzie update
- Select po BatchReview mógłby spowodwać out of memory
- nie możemy czyścić Sesji
- setFirstResult(i)
- setMaxResult(batchSize)
- potem em.flush em.clear
Batch Strumieniwanie
OrphanRemoval
- określa czy obiekty potomne, które nia mają odniesienia do obiektów nadrzędnych powinny być usunięte z bazy danych
Poziomy Izolacji transkacji
- read uncommited
- read committed
- Reapatable read
- Serializable
Read uncommited
- możliwy brudny odczyt,
- możliwy odczyt nie dający się powtórzyć
- możliwy odczyt widmo
- niemożliwy lost update
- każda transkacja możę odczytać każdy wiersz
- zapisujące nie dopuszczają innych zapisujących
Read commited
- niemożliwy brudny odczyt,
- możliwy odczyt niedający się powtórzy
- możliwy odczyt widmo.
- czytające dopuszczają wszystkie
- niezatwierdzone piszące blokują wszystkim innym transkacja
- domyślny poziom izolacji Specyfikacji JPA
Repeatable read
- możliwy odczyt widmo.
- czytające dopuszczają czytające
- zapisujące niedopuszczają żadnych
Serializable
żaden z niepożądanych odczytów nie jest możliwy. W praktyce oznacza to zablokowanie dostępu do całej tabeli. Niemożliwa jest modyfikacja i odczyt aż do momentu zakończenia transakcji.
- większość aplikacji nie jest potrzebna
- odczyt widma nie sprawia problemów
Budny odczyt
- odczyt zmiany wprowadzonej przez inna transkacje, która nie została jeszcze zatwierdzona
odczyty nie dające się powtórzyć
- jedna transakcja czyta element danych dwa razy i za każdym razem odczytuje inny stan
- inna transakcja mogła zapisać element danych i zatwierdzić dane pomiędzy dwoma odczytami
odczyty widmo
- gdy zapytanie transakcji jest uruchamiane dwukrotnie i drugi zestaw wyników zawiera dane, które nie były w pierwszym
- druga transkacja zrobiła inserta w tym czasie
utracona aktualizacja
- gdy dwie transkacje jednocześnie aktualizują element danych a druga transkacja zostanie anulowana
- w takim przypadku obie zmiany zostaną utracone
Jaki poziom izolacji wybrać?
- zbyt wysoki poziom izolacji negatywnie wpływa na skalowalność aplikacji
- zbyt niski poziom może spowodować może spowodować niedające się powtórzyć błędy
- należy wyeliminować poziom read uncommited - korzystanie z niezatwierdzonych zmian innej transkacji jest niebezpieczne
- więkoszość aplikacji niepotrzebuje serializable - więcej problemów z blokowaniem tabeli
- read commited jest domyślny ponieważ wraz z mechanizmem cachowania eliminuje problem odczytu nie dającego się powtórzyć
Optymistic Lock
- technika zarządzania współbieżnością
- zakłada, że konflikt w bazie są rzadkie i zamiast blokować dostęp do rekordu pozwala na równoległą modyfikacje
- konflikt jest wykryty i obsłużony przy zapisie
- realizowana jest przy pomocy wersjonowania rekordów
Sposoby wersjonowania
- przez pole licznika wersji oraz @Version (update where And version = )
- przy pomocy znacznika czasu
- wersjonowania bez znaczników czasu i wersji , w celu zsychnchronizowania robi Update z where And na każde pole
Kontekst utrwalania
- W jpa Entity Manager
- zarządza wszystkimi encjami w stanie persist
- automatyczne sprawdzanie modyfikacji wykrywane są te egzemplarze encji które zostały zmodyfikowane
- spełnia rolę cache pierwszego poziomu - zapamiętuje wszystkie egzemplarze encji przetwarzane w określonej jednostce pracy
- jak ładujemy jakąś encje to hibernate najpierw sprawdzi kontekts utrwalania
Jaki problem może wystąpić jęśli mamy dwie encje w stanie odłączonym które były pobrane w różnych kontekstach utrwalania i nie stworzyliśmy własnych equals oraz hash code
- jeśli były pobrane w różnych kontekstach utrwalania to będą traktowane jako różne pomimo , że odnoszą się do tego samego rekordu w bazie
- włąsny hashcode i equals rozwiązuje problem
- klucz bizesowy i porównywanie equals
Pobraliśmy egzemplarz klasy User w poprzednim kontekście utrwalania a teraz chemy go zmodyfikować, jak wygląda taka procedura
- najpierw wywołujemy merge - hibernate sprawdza czy trwały egzemplarz w kontekście utrwalania ma taki sam identyfikator co odłączony egzemplarz, który scaliliśmy
- w tym przykładzie kontekst utrwalania jest pusty więc Hibernate ładuje egzemplarz z tym id z bazy
- operacja merge kopiuje odłączony egzemplarz encji do załadowanego utrwalonego egzemplarza
- jeżeli nie było encji z takim id to Hibernate stworzy nowy egzemplarz
- merge może obługiwać te co są detached oraz transient
Pesymistic Lock
- strategia zarządzania współbieżnośćia
- zakłada, że konflitky w dostępie do danych są prawdopodobne
- zabezpiecza się przed nimi poprzez zablokowania rekordów na czas wykonania operacji
- negatywnie wpływa na wydajność aplikacji
Rodzaje pesymistic locków
-
Read Locking
- zapobiega zmianom w blokowanych rekordach przez inne transkacje ale pozwala na ich odczyt
- stosujemy gdy potrzebujemy, że dane nie zostaną zmienione przez inne transkacje przed zakończeniem operacji ale nie musimy blokować odczytów -
Write Locking
- zapobiega zmiana oraz odczytowi
Pesymistic Lock vs Optymistic
Optymistic
- konflikt są rządkie
- wersjonowanie rekordów bazie danych, aplikacja sprawdza czy wersja rekordu się nie zmieniła przed zapisem
- konfilkty rozwiązywane na poziomie aplikacji
- minimlany wpływ na wydajność
Pesymistic
- zakłada, że konflikty są prawdopodobne
- bezpośrednie blokowanie rekordów
- negatywy wpływ na wydajność
Co jeśli dojdzie do konfiliktu przy optymistic lock
- Hibernate rzuci Optymistic Lock exception
Jak zoptymalizować N + 1 używając Fetchmode ?
- Subselect jest dobra alternatywą do pobierania zachłannego
- gdy dojdzie do operacji na powiązanych kolekcjach hibernate wygeneruje jedno zapytanie subselect aby pobrać wszystkie bidy dla wszystki item jednym zapytaniem
Jak rozwiązać problem iloczynu kartenzjanśkiego używając FetchMode
- fetchmode select sprawi, że zamiast zapytania z JOIN, które może doprowiadzić do problemu wykona osobnego selecta