Wsparcie dla pola typu JSONB w PostgreSQL dla Spring Data JPA + Hibernate

Od wersji 9.4 PostgreSQL oferuje nowy typ danych którym jest JSONB. Wcześniej w wersji 9.2 został wprowadzony typ JSON który przechowuje dane w tym formacie w wersji tekstowej. Wymagało to parsowania danych przed wykonaniem jakiejkolwiek operacji na nich. JSONB przechowuje zdekomponowane dane binarne, dzięki czemu mamy do nich szybszy dostęp. Dodatkowo możemy ich użyć do tworzenia indeksów, joinów itp.

Wygląda to bardzo pięknie i równie dobrze sprawdza się w praktyce, jednak Hibernate nie wspiera natywnie tego rodzaju pól. Można to jednak obejść tworząc własny typ danych oraz mówiąc mu jak może ten typ zserializować do formatu JSON. W tym poście przejdziemy przez proces tworzenia własnego typu.

Przykładowy kod do tego postu można znaleźć na githubie pod adresem: https://github.com/mloza/spring-boot-jpa-jsonb-hibernate

Zaczynamy!

Na początek zaczniemy od zdefiniowania prostej encji która będzie zawierała pole z klasą którą chcemy serializować do JSONa. Klasa ta będzie miała kilka przykładowych pól, jakąś listę i mapę. Przykładowo może wyglądać w następujący sposób:

Następnie z wykorzystaniem tej klasy tworzymy encję:

Kolejnym krokiem jest stworzenie Hibernatowego typu który będzie umiał serializować i deserializować z JSONa naszą klasę. 

Mając już to wszystko, musimy na chwilę wrócić do naszej encji i dodać adnotacje mówiącą Hibernate, że do obsługi naszego pola powinien wykorzystać nasz typ. 

W tym momencie mamy już prawie wszystko. Ostatnim krokiem jest rozszerzenie dialektu PostgreSQL  aby powiedzieć Hibernate, że typ JAVA_OBJECT jest znany i powinien być obsługiwany. 

Nie zapomnijmy jeszcze w propertisach poinformować aplikacji, że powinna używać naszego dialektu zamiast domyślnego. Należy dodać linię:

Uruchomienie!

To wszystko pozwoli nam już uruichomić aplikację. Jednak dla ułatwienia interakcji z bazą danych, będizemy potrzebowali jeszcze stworzyć repozytorium JPA. Kod wygląda następująco:

Gdy mamy już wszystko możemy dodać test który wykona zapis i odczyt danych z bazy. Wygląda on następująco:

Użycie tego w ten sposób jest bardzo wygodne, nie zajmujemy się już serializacją czy deserializacją danych, wykonujemy query i dostajemy obiekt z którym możemy pracować. 

Jeśli sprawdzimy jak wpis wygląda w bazie otrzymamy na konsoli następujący wynik:

Querowanie danych w polu JSONB

Jak już wcześniej wspominałem po danych zapisanych w polach JSON i JSONB możemy querować i wyciągać wartości. Możemy do tego również użyć repozytoriów JPA wstawiając query do adnotacji metody @Query. Jendak jest to temat na oddzielny wpis, pokażę tylko przykładowe query które wygląda następująco:

Podsumowanie

Mimo, że użycie pola JSON w hibernate nie jest wspierane natywnie, to można z pomocą kilku klas dodać tą obsługę i działa to bardzo fajnie. Raz dodane wsparcie może być wielokrotnie używane w różnych miejscach. JSON daje nam elastyczność której czasem może brakować w relacyjnej bazie danych. Dzięki temu możemy połączyć dwa światy: RDS oraz NoSQL. Trzeba jednak pamiętać, że wykonywanie query na polach JSON może być nieco wolniejsze a dane w nich przechowywane mogą zajmować więcej miejsca niż gdyby były rozbite na pola w tabeli. 

Co do wielkości przechowywanego obiektu, udało mi się znaleźć informację, że można zapisać do 1GB danych w tym polu. 

Dodaj komentarz

Twój adres email nie zostanie opublikowany. Pola, których wypełnienie jest wymagane, są oznaczone symbolem *

This site uses Akismet to reduce spam. Learn how your comment data is processed.