Konwersja Encji w DTO.

Konwersja Encji w DTO.
AI
  • Rejestracja:prawie 10 lat
  • Ostatnio:ponad 3 lata
  • Postów:375
0

Zastanawiam się gdzie powinna odbywać się konwersja obiektu reprezentującego obiekt w bazie danych (JPA @Entity) na DTO (i odwrotnie). Widzę minimum trzy opcje:

  1. serwis do konwertowania @Entity -> DTO. Główny problem jaki tu widzę, że przyrostowo będzie zwiększać się liczba liinii w serwisie.

  2. w @Entity metoda toDto - wtedy do konwersji DTO -> @Entity musiałaby istnieć osobna klasa do konwersji. Plus na pewno taki, że załatwia to problem np. z dziedziczeniem / polimorfizmem (nie trzeba sprawdzać typu obiektu tylko z automatu można wywołać metodę która zwróci odpowiednie DTO). Problemy: ciężej będzie robić jakieś customowe DTO (abstrachując od założeń RESTa, w przypadku gdy coś byłoby łatwiej/wydajniej zrobić po stronie backendu i zwrócić jakiegoś customowego DTO).

  3. Osobna klasa dla @Entity -> @DTO i DTO -> @Entity. Z dwoma konstruktorami i dwoma polami: jeden z obiektem @Entity - wtedy DTO byłoby instancjonowane jakąś metodą. Drugi z DTO, wtedy pole z @Entity byłoby instancjonowane wyciągając coś np. z bazy danych.

Osobiście wydaje mi się, że druga lub trzecia opcja byłaby najlepsza. Tylko w trzeciej musiałbym znowu sprawdzać jakiego typu mam obiekt w przypadku gdybym miał w bazie zapisane obiekty kilku typów (wynikających z dziedziczenia).

Shalom
  • Rejestracja:ponad 21 lat
  • Ostatnio:około 3 lata
  • Lokalizacja:Space: the final frontier
  • Postów:26433
2

Pytanie jest bez sensu, bo poza CRUDowymi tutorialami nie istnieje coś takiego jak konwersja encji w dto taka jaką opisujesz, czyli jakieś mapowanie 1:1. Opcja 2 to już w ogóle bezsens. Jeśli robisz takie mapowania 1:1 to równie dobrze możesz lecieć encja na twarz i pchasz i w ogóle się nie bawić w jakieś mapowania.

Co więcej, w normalnej apikacji występuje taki twór jak logika domenowa i model bazodanowy w ogóle nie styka się nigdzie z DTO, bo pomiędzy nimi jest model domenowy który realizuje logikę biznesową aplikacji. Konwersja na obiekty domenowe następuje zaraz po pobraniu danych z bazy i realizuje ją jakaś wydzielona klasa, bo model bazodanowy generalnie nie będzie miał nic wspólnego (strukturalnie) z modelem domenowym. Konwersja na DTO może faktycznie leżeć w jakimś korzeniu obiektów domenowych, a może też być wyciągnięta gdzieś do osobnej klasy. Kwestia rozmiaru.


"Nie brookliński most, ale przemienić w jasny, nowy dzień najsmutniejszą noc - to jest dopiero coś!"
edytowany 1x, ostatnio: Shalom
MrMadMatt
  • Rejestracja:ponad 9 lat
  • Ostatnio:3 dni
  • Postów:373
0
Shalom napisał(a):

Pytanie jest bez sensu, bo poza CRUDowymi tutorialami nie istnieje coś takiego jak konwersja encji w dto taka jaką opisujesz, czyli jakieś mapowanie 1:1. Opcja 2 to już w ogóle bezsens. Jeśli robisz takie mapowania 1:1 to równie dobrze możesz lecieć encja na twarz i pchasz i w ogóle się nie bawić w jakieś mapowania.

Co więcej, w normalnej apikacji występuje taki twór jak logika domenowa i model bazodanowy w ogóle nie styka się nigdzie z DTO, bo pomiędzy nimi jest model domenowy który realizuje logikę biznesową aplikacji.

A co w przypadku gdy model biznesowy jest wymodelowany w klasach oblepionymi JPA? Mi się wydaje że konwersja encja->dto jest dość częsta.

Wracając do autora:

Co do drugiego, mapowanie 1:1 -> wydaje mi się że to ma sens tylko i wyłączenie w przypadku gdy masz beznadziejne encje JPA z dwukierunkowymi relacjami a na parsowaniu encji na JSONa dostajesz OutOfMemory albo coś innego. Ewentualnie pola w encji są beznadziejnie nazwane i chcesz w kontrakcie je naprostować np. z psl na pesel.

A co do tego że serwis Ci się rozrośnie jak konwersję na DTO bedziesz miał w serwisie:

  1. Mapowanie przenosisz do klasy np. Function<MyEntity, MyDto>
  2. Serwis dzielisz na podserwisy które realizują pojedyncze zadanie.
Shalom
  • Rejestracja:ponad 21 lat
  • Ostatnio:około 3 lata
  • Lokalizacja:Space: the final frontier
  • Postów:26433
0

A co w przypadku gdy model biznesowy jest wymodelowany w klasach oblepionymi JPA

To masz dużo większy problem niż mapowanie ;)

Mi się wydaje że konwersja encja->dto jest dość częsta.

Jeśli piszesz generic cruda, to możliwe że tak. Tylko po co wtedy w ogóle cokolwiek pisać? Wrzucasz do projektu Spring-Data-Rest i wszystko się samo generuje w 2 minuty, nie trzeba pisać żadnego kodu... Samo się wszystko ładnie przepycha sql<->json.


"Nie brookliński most, ale przemienić w jasny, nowy dzień najsmutniejszą noc - to jest dopiero coś!"
edytowany 1x, ostatnio: Shalom
KamilAdam
  • Rejestracja:ponad 6 lat
  • Ostatnio:2 dni
  • Lokalizacja:Silesia/Marki
  • Postów:5505
0
Aisekai napisał(a):

Zastanawiam się gdzie powinna odbywać się konwersja obiektu reprezentującego obiekt w bazie danych (JPA @Entity) na DTO (i odwrotnie).

  • Odpowiedź zgodna z OOP, DDD, Czystą Architekturą i innymi świętymi księgami -> nigdzie ponieważ między JPA @Entity a DTO jest jeszcze Encja Biznesowa z Logiką Biznesową
  • Odpowiedź zgodna z doświadczeniem zawodowego klepacza korpo crudów - nigdzie ponieważ Encja na twarz i pchasz :'( . Masz jedno uniwersalne DTO-JPA Entity które przechodzi cały system :'(

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 2x, ostatnio: KamilAdam
S9
  • Rejestracja:ponad 10 lat
  • Ostatnio:6 miesięcy
  • Lokalizacja:Warszawa
  • Postów:3573
1

Tak jak przedmówcy pisali -> model domenowy nie powinien zależeć od warstwy persystencji ani prezentacji!
Powinienes definionwac interfejsy na operacje np. Option<Product> getProductDetails(ProductId productId) i ten model(Product) powinien być zależny tylko od innych modeli, ewentualnie jakiś bibliotek typu Vavr ;)
Model domenowy zależy od niej samej, use'casy i porty zależą od modelu domenowego a reszta od tych dwóch.


"w haśle <młody dynamiczny zespół> nie chodzi o to ile masz lat tylko jak często zmienia się skład"
Charles_Ray
  • Rejestracja:około 17 lat
  • Ostatnio:3 minuty
  • Postów:1880
0

Ja bym po prostu zwrócił encję w kontrolerze, mniej kodu.


”Engineering is easy. People are hard.” Bill Coughran
MrMadMatt
  • Rejestracja:ponad 9 lat
  • Ostatnio:3 dni
  • Postów:373
1
Shalom napisał(a):

A co w przypadku gdy model biznesowy jest wymodelowany w klasach oblepionymi JPA

To masz dużo większy problem niż mapowanie ;)

No właśnie sam nie wiem, jak dużym problemem jest żenienie obiektów domenowych z JPA. Np. tutaj: https://bottega.com.pl/pdf/materialy/ddd/ddd1.pdf u Sławka Sobótki agregat jest oblepiony adnotacjami JPA. Trochę off-topując: czy to jest błąd? Czy warto być "domenowym-nazistą" i walczyć o adnotacyjnie-czystą-domenę? Bo takie zabiegi jak u Sobótki spotkałem nieraz i sam nie wiem, może ktoś się podzieli przemyśleniami. ;)

UN
Ale DDD to jest zupełnie inna architektura aplikacji, trzeba wybrać jedną i się jej trzymać. BTW przy GWT takie podejście zupełnie odpada. Jakiś rodzaj maperów miałem chyba w każdym projekcie bo jak ktoś wspomniał nie chcesz przesyłać całej encji do warstwy prezentacji
Charles_Ray
DDD nie jest architekturą aplikacyjną, ale podejściem do projektowania oprogramowania
S9
  • Rejestracja:ponad 10 lat
  • Ostatnio:6 miesięcy
  • Lokalizacja:Warszawa
  • Postów:3573
1

To nie jest dobre żeby mieszać encje JPA z domeną, bo są pewne rzeczy które sa wymuszane przez to JPA, np konstruktor domyślny. Dochodzi jeszcze wydajność, to że na ogół nie potrzebujesz całej encji bazodanowej wczytanej, magie z różnymi proxy itp itd


"w haśle <młody dynamiczny zespół> nie chodzi o to ile masz lat tylko jak często zmienia się skład"
Zobacz pozostały 1 komentarz
Charles_Ray
Pragmatyzm. Albo robisz 5 warstw, albo idziesz na skróty - Ty jesteś kapitanem swojego okrętu. Warto jeszcze wspomnieć o CQRS, w stosie do odczytu praktycznie wyrzuca się dane z bazy na front.
S9
Ja bym nie mapowak na JPA bo bym nie korzystał z JPA
MrMadMatt
Dobra wszystko fajnie, nawet @KamilAdam poniżej w poście sugeruje że JPA to ble, no więc skoro wiedza o tym że JPA to zło jest tak powszechna to czego wszędzie jest tego tak napchane że żadna oferta pracy nie obędzie się bez Hibernate?
S9
Myślę że to forum nie jest reprezentatywne. No a poza tym i tak na ogół często nie potrzebujesz całej encji JPA więc tak czy owak mapujesz
KamilAdam
@MrMadMatt: słabo szukasz. W większości firm w których pracowałem nie używaliśmy JPA/Hibernate tylko JOOQ czy JdbcTemplate/Jdbi
KamilAdam
  • Rejestracja:ponad 6 lat
  • Ostatnio:2 dni
  • Lokalizacja:Silesia/Marki
  • Postów:5505
0
scibi92 napisał(a):

To nie jest dobre żeby mieszać encje JPA z domeną, bo są pewne rzeczy które sa wymuszane przez to JPA, np konstruktor domyślny. Dochodzi jeszcze wydajność, to że na ogół nie potrzebujesz całej encji bazodanowej wczytanej, magie z różnymi proxy itp itd

I tak dochodzimy do wniosku że JPA to zło i powinni tego zakazać


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
Shalom
  • Rejestracja:ponad 21 lat
  • Ostatnio:około 3 lata
  • Lokalizacja:Space: the final frontier
  • Postów:26433
0

@MrMadMatt nie wiem, ja nie pracuje z CRUDami i u mnie te modele są tak od siebie różne że w ogóle nie ma za bardzo jak mówić o "mapowaniu" czegokolwiek.


"Nie brookliński most, ale przemienić w jasny, nowy dzień najsmutniejszą noc - to jest dopiero coś!"

Zarejestruj się i dołącz do największej społeczności programistów w Polsce.

Otrzymaj wsparcie, dziel się wiedzą i rozwijaj swoje umiejętności z najlepszymi.