clean architecture JPA vs JDBC

clean architecture JPA vs JDBC
EZ
  • Rejestracja:około 5 lat
  • Ostatnio:ponad 4 lata
  • Postów:32
1

Co jest lepszym wyborem JPA czy JDBC w przypadku gdy chce zachować obiekty domeny zupełnie nieświadome warstwy persystencji? Używając JPA mógłbym skorzystać z XML'a do mapowania jednak JPA nadal wprowadza wymagania takie jak bezargumentowy konstruktor co infekuje obiektu domeny i w przypadku klas z polami niezmiennymi może być problematyczne. Mógłbym za każdym razem tworzyć oddzielny model dla warstwy persystencji jednak wprowadza to sporo dodatkowej pracy i jednocześnie pozbywam się zalet ORM takich jak lazy loading i śledzenie zmian. Czy jest sens w takiej sytuacji używać JPA kiedy chce zachować 100%-ową niezależność warstwy domeny? Czy lekkie uzależnienie warstwy domeny od persysencji jest lepszym wyborem niż całkowita rezygnacja z ORM? W większych projektach używanie samego JDBC (try, catch) wydaje się niezbyt rozsądne.

KamilAdam
  • Rejestracja:ponad 6 lat
  • Ostatnio:8 dni
  • Lokalizacja:Silesia/Marki
  • Postów:5505
1
eziomou napisał(a):

pozbywam się zalet ORM takich jak lazy loading

lazy loading z bazy danych nie jest zaletą tylko drogą na skróty (jak całe JPA)

W większych projektach używanie samego JDBC (try, catch) wydaje się niezbyt rozsądne.

Jest jeszcze JOOQ, JDBI, JdbcTemplate i pare innych rozwiązań ale ich nie używałem


Mama called me disappointment, Papa called me fat
Każdego eksperta można zastąpić backendowcem który ma się douczyć po godzinach. Tak zostałem ekspertem AI, Neo4j i Nest.js . Przez mianowanie
edytowany 1x, ostatnio: KamilAdam
mad_penguin
mad_penguin
droga na skróty nie brzmi jak wada :)
EZ
zobaczyłem na szybko JOOQ, wydaje się podobne do JDBC ale bardziej przyjazne
S9
  • Rejestracja:ponad 10 lat
  • Ostatnio:5 miesięcy
  • Lokalizacja:Warszawa
  • Postów:3573
3

W sumie sam poniekąd sobie odpowiedziałeś - jak masz Clean Architecture to masz odzielne encje JPA i oddzielne biznesowe. Należy zwrócić uwagę że korzystanie z encji JPA w wyższych warstwach jest problematyczne(np lazy loading po zakończeniu transakcji, dirty checking itp)
Dodatkowo też zaleca się stosowanie Value Objectow w modelu domenowym, zamiast mieć String email lepiej mieć Email email bo to jest o wiele czytelniejsze, a gdy masz encje biznesowe związane z JPA to musiałbyś mappery, albo stosować zwykle Stringi, Integery itp w encji JPA.
A to tym że Twoje pytanie sugeruje ze nie znasz w pełni celów czystej architektury nie wspomnę ;)


"w haśle <młody dynamiczny zespół> nie chodzi o to ile masz lat tylko jak często zmienia się skład"
edytowany 1x, ostatnio: scibi92
EZ
  • Rejestracja:około 5 lat
  • Ostatnio:ponad 4 lata
  • Postów:32
0

@scibi92 właśnie o to pytam, czy jest sens korzystać z JPA jeśli chcemy mieć zupełnie nieświadomą warstwę domeny? Kolega wyżej @KamilAdam napisał, że lazy loading jest drogą na skróty ale w przypadku nieprawidłowo zaprojektowanych agregatów w formie wielkich klastrów z masą zagnieżdżonych encjij. Jeśli mamy prawidłowo zaprojektowany agregat ze stałą liczbą encji, powiedzmy 20 encji, które z również mają po 20 encji, w tym wypadku lazy loading jest dużą optymalizacją

A to tym że Twoje pytanie sugeruje ze nie znasz w pełni celów czystej architektury nie wspomnę ;)

W takim razie byłbym wdzięczny gdybyś mi wytknął błąd

S9
  • Rejestracja:ponad 10 lat
  • Ostatnio:5 miesięcy
  • Lokalizacja:Warszawa
  • Postów:3573
2

Ale JPA to nie warstwa domeny tylko warstwa persystencji! Odnośnie zastosowania Clean Architecture - celem jest m. in.
1)możliwość opoźnienia decyzji "technicznych" - na przykład czy stosujemy SQL, noSQL czy pliki albo po prostu RAM
2)ułatwienie zmian technologicznych - np zmianę Jdbc na JPA


"w haśle <młody dynamiczny zespół> nie chodzi o to ile masz lat tylko jak często zmienia się skład"
EZ
  • Rejestracja:około 5 lat
  • Ostatnio:ponad 4 lata
  • Postów:32
0

@scibi92 jak najbardziej (oprócz tego, że JPA to warstwa), nie wiem co w mojej wypowiedzi sugeruje coś przeciwnego?

edytowany 1x, ostatnio: eziomou
S9
  • Rejestracja:ponad 10 lat
  • Ostatnio:5 miesięcy
  • Lokalizacja:Warszawa
  • Postów:3573
0

Zacząłeś trochę z drugiej strony, ale może się mylę. Tak czy inaczej należy pamiętać że encja w rozumieniu ORM to coś innego niż encja biznesowa.


"w haśle <młody dynamiczny zespół> nie chodzi o to ile masz lat tylko jak często zmienia się skład"
EZ
  • Rejestracja:około 5 lat
  • Ostatnio:ponad 4 lata
  • Postów:32
0

@scibi92 wydaje mi się, że nie byłoby tematu gdybym nie znał tej różnicy.

S9
  • Rejestracja:ponad 10 lat
  • Ostatnio:5 miesięcy
  • Lokalizacja:Warszawa
  • Postów:3573
1

Faktycznie, może źle Cię zrozumiałem. Myślę że sam fakt że mamy osobny model persystencji niż domenowy to nie jest wada jakiegoś rozwiązania, np w JOOQ też masz modele, no i na ogół model domenowy. Na ogol proces mapowania nie jest skomplikowany ani kosztowny. Ja bym JPA nie użył ale tylko dlatego że nie uważam JPA za najlepsza technologie delikatnie rzecz ujmując ;)


"w haśle <młody dynamiczny zespół> nie chodzi o to ile masz lat tylko jak często zmienia się skład"
edytowany 1x, ostatnio: scibi92
EZ
a możesz napisać czego używasz?
Shalom
  • Rejestracja:około 21 lat
  • Ostatnio:prawie 3 lata
  • Lokalizacja:Space: the final frontier
  • Postów:26433
2

Nie bardzo rozumiem pytanie. Masz jakiśtam moduł persistence który potrafi na podstawie jakiegoś persistent store wypluwać obiekty domenowe. To czy dzieje się to za pomocą JPA, JDBC czy parsowania xmla nie ma znaczenia.


"Nie brookliński most, ale przemienić w jasny, nowy dzień najsmutniejszą noc - to jest dopiero coś!"
EZ
  • Rejestracja:około 5 lat
  • Ostatnio:ponad 4 lata
  • Postów:32
0

@Shalom chodzi mi o to, żeby zrealizować w 100% clean architecture i jednocześnie stosować JPA muszę mieć dwa modele, a i tak nie daje mi to prawie żadnych zalet jak lazy-loading i czy w tym przypadku lepszy będzie lekki kompromis i małe dopasowanie obiektów domeny czy rezygnacja z ORM na rzecz jakiegoś lżejszego rozwiązania jak właśnie JDBC

wiem, że pewnie nie ma konkretnej odpowiedzi ale może macie jakieś doświadczenie w tym kierunku, co byłoby bardzo pomocne

edytowany 1x, ostatnio: eziomou
S9
  • Rejestracja:ponad 10 lat
  • Ostatnio:5 miesięcy
  • Lokalizacja:Warszawa
  • Postów:3573
2

Akurat ciężko lazy loading uznać za zalete ze względu na wydajność :)


"w haśle <młody dynamiczny zespół> nie chodzi o to ile masz lat tylko jak często zmienia się skład"
Shalom
  • Rejestracja:około 21 lat
  • Ostatnio:prawie 3 lata
  • Lokalizacja:Space: the final frontier
  • Postów:26433
2

muszę mieć dwa modele

O ile nie klepiesz CRUDa, to i tak musisz mieć. I nie że zmusza cię do tego jakaś technologia, tylko zwyczajnie zdrowy rozsądek i domena. Obiekty domenowe są generalnie dużo bardziej rozbudowane i dość naiwnym jest wiara w to że będą specjalnie podobne do modelu danych. Tak jak mówie -> to ma miejsce tylko jak piszesz generic cruda.

zalet jak lazy-loading

Jeśli ktoś uważa n+1 select za zaletę to decyzja JPA vs JDBC jest twoim najmniejszym problemem...

Ale tu właśnie wychodzi trochę niezrozumienie clean architecture. Cały myk polega właśnie na tym, żebyś tak to zaimplementował, żeby technologia persystencji danych nie miała żadnego znaczenia dla działania systemu ani w ogóle dla kodu domenowego.


"Nie brookliński most, ale przemienić w jasny, nowy dzień najsmutniejszą noc - to jest dopiero coś!"
edytowany 1x, ostatnio: Shalom
Charles_Ray
  • Rejestracja:około 17 lat
  • Ostatnio:około 17 godzin
  • Postów:1874
4

Dodałbym do posta @Shalom że czysta architektura nie oznacza najlepszej możliwej dla danego problemu :) czysta architektura nie powinna być celem samym w sobie


”Engineering is easy. People are hard.” Bill Coughran
edytowany 1x, ostatnio: Charles_Ray
EZ
  • Rejestracja:około 5 lat
  • Ostatnio:ponad 4 lata
  • Postów:32
0

@Charles_Rey
Dzieki, właśnie stąd pytanie o kompromisy

@Shalom

Jeśli ktoś uważa n+1 select za zaletę to decyzja JPA vs JDBC jest twoim najmniejszym problemem...

Nie wiedziałem że lazy loading wiąże się z wczytywaniem za każdym razem całych hierarchii encji. Człowiek uczy się przez całe życie...

Charles_Ray
No a na czym polega „lazy” :) wczytywanie on demand
EZ
Tak ale jeśli agregat nie ma głębokiej hierarchii dzieci-encji to prawidłowo stosowany lazy loading w zależności od modelu może być pomocny. Sam nie jestem fanem ale nie rozumiem opini które zupełnie negują jego przydatność przez nieprawidłowe korzystanie jak n+1
Charles_Ray
Bo to jest side effect, który ciężko wychwycić podczas dev i testów, rozwala dopiero produkcje :)
EZ
Jasne zgadzam się ale jeśli już ktoś zajmujący się warstwą utrwalania decyduje się na lazy loading to chyba jest to podyktowane modelem do którego ma dostęp I rozumie co się z tym wiąże
Charles_Ray
To dość odważne założenie :) gdyby tak było to testy automatyczne nie byłyby potrzebne- ale to już filozoficzna dyskusja. Myśle, ze znalazłoby się jakieś uzasadnione uzycie lazy loadingu, nie mówię ze nie, ale zwykle są to błędne decyzje w stylu „bo mogę”.
somekind
Moderator
  • Rejestracja:około 17 lat
  • Ostatnio:dzień
  • Lokalizacja:Wrocław
2
eziomou napisał(a):

Mógłbym za każdym razem tworzyć oddzielny model dla warstwy persystencji jednak wprowadza to sporo dodatkowej pracy

Napisanie klasy i jej zmapowanie, nawet ręcznie, to jest troszeczkę dodatkowej pracy, która oszczędza sporo czasu na debugowaniu i poprawianiu.

jednocześnie pozbywam się zalet ORM takich jak lazy loading i śledzenie zmian.

Takie myki są akceptowalne, jak masz prostą domenę, anemiczny model, jesteś w stanie wszystko ogarnąć transaction scriptem, i wiesz co robisz, czyli np. nie wysyłasz tych biznesowo-bazowych encji na widok, bo wtedy n+1 masz gwarantowane.

edytowany 1x, ostatnio: somekind
Zobacz pozostały 1 komentarz
Shalom
@Charles_Ray: nie koniecznie :D Ktoś kiedyś wymyślił taki hax jak Open session in view :D
Charles_Ray
Racja, zgoda. Poziom: Vietnam. Oddając honor - wydaje mi się że ten filtr był/jest domyślnie włączony w Spring Boocie
Charles_Ray
To mnie jeszcze nie boli, tak długo jak jest opt-in, a nie opt-out
somekind
Nie znam się na szczegółach implementacji w jakichś javowych frameworkach, w ogólności wyjątku być nie musi. Ale jeśli w Javie macie wtedy wyjątek, no to faktycznie jest to jakaś zaleta.
AK
  • Rejestracja:ponad 6 lat
  • Ostatnio:12 dni
  • Postów:3561
2

Pewne zalety JPA (tak!) jak obserwowanie stanu obiektu, śledzenie zmian - BYŁY zaletami, jak to był desktop.

Są totalnie zbędne we współczesnych aplikacjach webowych, gdzie odczyt a zmiany/zapis to zuuupełnie inne części systemu, inny czas, być może nawet inny host. A kosztują pod względem wydajności, dużej komplikacji itd...


Bo C to najlepszy język, każdy uczeń ci to powie
Charles_Ray
odczyt a zmiany/zapis to zuuupełnie inne części systemu, inny czas, być może nawet inny host. tego przyznam, że nie rozumiem, może jest za późno :) pobranie encji/agregatu z bazy celem wprowadzenia zmiany stanu odbywa się w tej samej transakcji - inaczej jakby miała działać transakcja?
KE
Myślę że chodzi o CQRS level 70, czyli osobny komponent (mikroserwis?) do odczytu danych, działający być może na innej maszynie, skalowany odrębnie od reszty.
AK
zmiana o jakiej piszesz @Charles_Ray jest szybka i lokalna, nie wydaje mi się aby była potrzeba automatycznego śledzenia zmian
Charles_Ray
@kelog: no to wtedy się nie zgadzam bo po sieci przecież nie przesyłasz sesji JPA :) @AnyKtokolwiek: Zależy od komplikacji operacji na agregacie, rozpatrywałbym case by case chyba.
Kliknij, aby dodać treść...

Pomoc 1.18.8

Typografia

Edytor obsługuje składnie Markdown, w której pojedynczy akcent *kursywa* oraz _kursywa_ to pochylenie. Z kolei podwójny akcent **pogrubienie** oraz __pogrubienie__ to pogrubienie. Dodanie znaczników ~~strike~~ to przekreślenie.

Możesz dodać formatowanie komendami , , oraz .

Ponieważ dekoracja podkreślenia jest przeznaczona na linki, markdown nie zawiera specjalnej składni dla podkreślenia. Dlatego by dodać podkreślenie, użyj <u>underline</u>.

Komendy formatujące reagują na skróty klawiszowe: Ctrl+B, Ctrl+I, Ctrl+U oraz Ctrl+S.

Linki

By dodać link w edytorze użyj komendy lub użyj składni [title](link). URL umieszczony w linku lub nawet URL umieszczony bezpośrednio w tekście będzie aktywny i klikalny.

Jeżeli chcesz, możesz samodzielnie dodać link: <a href="link">title</a>.

Wewnętrzne odnośniki

Możesz umieścić odnośnik do wewnętrznej podstrony, używając następującej składni: [[Delphi/Kompendium]] lub [[Delphi/Kompendium|kliknij, aby przejść do kompendium]]. Odnośniki mogą prowadzić do Forum 4programmers.net lub np. do Kompendium.

Wspomnienia użytkowników

By wspomnieć użytkownika forum, wpisz w formularzu znak @. Zobaczysz okienko samouzupełniające nazwy użytkowników. Samouzupełnienie dobierze odpowiedni format wspomnienia, zależnie od tego czy w nazwie użytkownika znajduje się spacja.

Znaczniki HTML

Dozwolone jest używanie niektórych znaczników HTML: <a>, <b>, <i>, <kbd>, <del>, <strong>, <dfn>, <pre>, <blockquote>, <hr/>, <sub>, <sup> oraz <img/>.

Skróty klawiszowe

Dodaj kombinację klawiszy komendą notacji klawiszy lub skrótem klawiszowym Alt+K.

Reprezentuj kombinacje klawiszowe używając taga <kbd>. Oddziel od siebie klawisze znakiem plus, np <kbd>Alt+Tab</kbd>.

Indeks górny oraz dolny

Przykład: wpisując H<sub>2</sub>O i m<sup>2</sup> otrzymasz: H2O i m2.

Składnia Tex

By precyzyjnie wyrazić działanie matematyczne, użyj składni Tex.

<tex>arcctg(x) = argtan(\frac{1}{x}) = arcsin(\frac{1}{\sqrt{1+x^2}})</tex>

Kod źródłowy

Krótkie fragmenty kodu

Wszelkie jednolinijkowe instrukcje języka programowania powinny być zawarte pomiędzy obróconymi apostrofami: `kod instrukcji` lub ``console.log(`string`);``.

Kod wielolinijkowy

Dodaj fragment kodu komendą . Fragmenty kodu zajmujące całą lub więcej linijek powinny być umieszczone w wielolinijkowym fragmencie kodu. Znaczniki ``` lub ~~~ umożliwiają kolorowanie różnych języków programowania. Możemy nadać nazwę języka programowania używając auto-uzupełnienia, kod został pokolorowany używając konkretnych ustawień kolorowania składni:

```javascript
document.write('Hello World');
```

Możesz zaznaczyć również już wklejony kod w edytorze, i użyć komendy  by zamienić go w kod. Użyj kombinacji Ctrl+`, by dodać fragment kodu bez oznaczników języka.

Tabelki

Dodaj przykładową tabelkę używając komendy . Przykładowa tabelka składa się z dwóch kolumn, nagłówka i jednego wiersza.

Wygeneruj tabelkę na podstawie szablonu. Oddziel komórki separatorem ; lub |, a następnie zaznacz szablonu.

nazwisko;dziedzina;odkrycie
Pitagoras;mathematics;Pythagorean Theorem
Albert Einstein;physics;General Relativity
Marie Curie, Pierre Curie;chemistry;Radium, Polonium

Użyj komendy by zamienić zaznaczony szablon na tabelkę Markdown.

Lista uporządkowana i nieuporządkowana

Możliwe jest tworzenie listy numerowanych oraz wypunktowanych. Wystarczy, że pierwszym znakiem linii będzie * lub - dla listy nieuporządkowanej oraz 1. dla listy uporządkowanej.

Użyj komendy by dodać listę uporządkowaną.

1. Lista numerowana
2. Lista numerowana

Użyj komendy by dodać listę nieuporządkowaną.

* Lista wypunktowana
* Lista wypunktowana
** Lista wypunktowana (drugi poziom)

Składnia Markdown

Edytor obsługuje składnię Markdown, która składa się ze znaków specjalnych. Dostępne komendy, jak formatowanie , dodanie tabelki lub fragmentu kodu są w pewnym sensie świadome otaczającej jej składni, i postarają się unikać uszkodzenia jej.

Dla przykładu, używając tylko dostępnych komend, nie możemy dodać formatowania pogrubienia do kodu wielolinijkowego, albo dodać listy do tabelki - mogłoby to doprowadzić do uszkodzenia składni.

W pewnych odosobnionych przypadkach brak nowej linii przed elementami markdown również mógłby uszkodzić składnie, dlatego edytor dodaje brakujące nowe linie. Dla przykładu, dodanie formatowania pochylenia zaraz po tabelce, mogłoby zostać błędne zinterpretowane, więc edytor doda oddzielającą nową linię pomiędzy tabelką, a pochyleniem.

Skróty klawiszowe

Skróty formatujące, kiedy w edytorze znajduje się pojedynczy kursor, wstawiają sformatowany tekst przykładowy. Jeśli w edytorze znajduje się zaznaczenie (słowo, linijka, paragraf), wtedy zaznaczenie zostaje sformatowane.

  • Ctrl+B - dodaj pogrubienie lub pogrub zaznaczenie
  • Ctrl+I - dodaj pochylenie lub pochyl zaznaczenie
  • Ctrl+U - dodaj podkreślenie lub podkreśl zaznaczenie
  • Ctrl+S - dodaj przekreślenie lub przekreśl zaznaczenie

Notacja Klawiszy

  • Alt+K - dodaj notację klawiszy

Fragment kodu bez oznacznika

  • Alt+C - dodaj pusty fragment kodu

Skróty operujące na kodzie i linijkach:

  • Alt+L - zaznaczenie całej linii
  • Alt+, Alt+ - przeniesienie linijki w której znajduje się kursor w górę/dół.
  • Tab/⌘+] - dodaj wcięcie (wcięcie w prawo)
  • Shit+Tab/⌘+[ - usunięcie wcięcia (wycięcie w lewo)

Dodawanie postów:

  • Ctrl+Enter - dodaj post
  • ⌘+Enter - dodaj post (MacOS)