Konwersja Encji w DTO.

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).

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.

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.
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.

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 :'(
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.

0

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

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. ;)

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

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ć

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.

1 użytkowników online, w tym zalogowanych: 0, gości: 1