mapowanie obiektów w streamie // Spring data JPA

0

Hej, próbuję napisać aplikacje w której implementuję klasę abstrakcyjną produkt, która posiada 3 podklasy: jedzenie, produkt medyczny i produkt higieniczny (single table). Do tej hierarchii dziedziczenia utworzyłem fabrykę (wydaje się dobrym pomysłem, ale może nie jest?) która pobiera product dto i na podstawie cech produktu danych jedynie dla odpowiedniej podklasy zwraca jej instancje. Stworzyłem rozwiązanie które działa i dodaje wszystkie produkty :

 Set<Product> products = new HashSet<>();
        for(ProductDTO product : source.getProducts()){
            products.add(ProductFactoryImplementation.getInstance(product));
        }

ale moim pierwszym pomysłem było napisanie czegoś takiego, co okazało się nieskuteczne ponieważ zwraca null :

  Set<Product> products = source.getProducts().stream()
                .map(ProductFactoryImplementation::getInstance)
                .collect(Collectors.toSet());

dlaczego ten stream nie działa a to pierwsze podejście tak? Jeśli potrzeba to udostępnie więcej kodu
Pozdrawiam

0

.map((p) -> ProductFactoryImplementation::getInstance(p)) <- czy tak też nie działa

2
Wiktor89Bdg napisał(a):

implementuję klasę abstrakcyjną produkt, która posiada 3 podklasy: jedzenie, produkt medyczny i produkt higieniczny (single table).

Jeśli dobrze zgaduję kontekst, to średniawy pomysł takiego cięcia na klasy / implementacji JPA *)

Albo klasy są bardzo podobne, to w ujęciu bazodanowych nie warto tego dziedziczenia robić (to tylko dodatkowy atrybut).
Albo są rozwojowe i dalekie (np produkt medyczny przywleka w polach pól wiedzy ze studiów medycznych), to implementacja jako signle table jest najgorsza.

*) Niestety, obecność bazy (oraz przyszłych zastosowań systemu, który chciałby być jak najbardziej uniwersalny bez nieustannego dziubania w kodzie) się mocno kłóci z (szkolnym) dziedziczeniem.

O ile jest to ci narzucone, i musisz, to pal, ale się nie zaciągaj. - to zła nauka.

0
_13th_Dragon napisał(a):

.map((p) -> ProductFactoryImplementation::getInstance(p)) <- czy tak też nie działa

dodałem kropkę zamiast dwukropka ale też nie działa. Zastanawiam się czy aby nie trzeba by było zaimplementować funkcjonalnego interfejsu z tą fabryką?

0
ZrobieDobrze napisał(a):
Wiktor89Bdg napisał(a):

implementuję klasę abstrakcyjną produkt, która posiada 3 podklasy: jedzenie, produkt medyczny i produkt higieniczny (single table).

Jeśli dobrze zgaduję kontekst, to średniawy pomysł takiego cięcia na klasy / implementacji JPA *)

Albo klasy są bardzo podobne, to w ujęciu bazodanowych nie warto tego dziedziczenia robić (to tylko dodatkowy atrybut).
Albo są rozwojowe i dalekie (np produkt medyczny przywleka w polach pól wiedzy ze studiów medycznych), to implementacja jako signle table jest najgorsza.

*) Niestety, obecność bazy (oraz przyszłych zastosowań systemu, który chciałby być jak najbardziej uniwersalny bez nieustannego dziubania w kodzie) się mocno kłóci z (szkolnym) dziedziczeniem.

O ile jest to ci narzucone, i musisz, to pal, ale się nie zaciągaj. - to zła nauka.

Moim celem jest napisanie aplikacji służącej do transportu gdzie paczka będzie posiadać listę produktów, które mogą potrzebować różnych warunków transportu. Klasy są dość podobne i różnią się 1-3 atrybutami.

1

czy to: ProductFactoryImplementation.getInstance(product) -> z ProductDTO tworzy Product?

0
_13th_Dragon napisał(a):

czy to: ProductFactoryImplementation.getInstance(product) -> z ProductDTO tworzy Product?

public static Product getInstance(ProductDTO source) {
        Product product = null;

        if (source.getFoodType() != null) {
            product = new FoodProduct(
                    source.getName(),
                    source.getExpirationDate(),
                    source.getDescription(),
                    source.getWeight(),
                    source.getAmount(),
                    source.getReserved(),
                    source.isFragile(),
                    source.getState(),
                    source.getFoodType());
        }

        if (source.getHygienePurpose() != null) {
            product = new HygieneProduct(
                    source.getName(),
                    source.getExpirationDate(),
                    source.getDescription(),
                    source.getWeight(),
                    source.getAmount(),
                    source.getReserved(),
                    source.isFragile(),
                    source.getState(),
                    source.getHygienePurpose());
        }

        if (source.getMedicalPurpose() != null) {
            product = new MedicalProduct(
                    source.getName(),
                    source.getExpirationDate(),
                    source.getDescription(),
                    source.getWeight(),
                    source.getAmount(),
                    source.isFragile(),
                    source.getReserved(),
                    source.getState(),
                    source.getMedicalPurpose()
            );

        }
        return product;
    }

zastanawiam się nad zrobieniem konstruktora w klasie produkt i tworzeniem każdej instancji poprzez przekazywanie obiektu produkt do konstruktora podklas, żeby było mniej edytowania

2
Wiktor89Bdg napisał(a):

Moim celem jest napisanie aplikacji służącej do transportu gdzie paczka będzie posiadać listę produktów, które mogą potrzebować różnych warunków transportu. Klasy są dość podobne i różnią się 1-3 atrybutami.

Zamiast szkolnego dziedziczenia SzczegółowyTowar : AbststrakcyjnyTowar (relacja jest)

proponuję relację ma

Towar {
  String atrybut1;
 // atrybuty proste
  
}

lub

Towar { 
   Kategoria k;
   // obiektowe
}

Sztywne dziedziczenie dla prowadzenia grup towarów / klientów / whatever tylko w szkole wygląda dobrze, ale zabija w profesjonalnym programowaniu bazodanowym

0
ZrobieDobrze napisał(a):
Wiktor89Bdg napisał(a):

Moim celem jest napisanie aplikacji służącej do transportu gdzie paczka będzie posiadać listę produktów, które mogą potrzebować różnych warunków transportu. Klasy są dość podobne i różnią się 1-3 atrybutami.

Zamiast szkolnego dziedziczenia SzczegółowyTowar : AbststrakcyjnyTowar (relacja jest)

proponuję relację ma

Towar {
  String atrybut1;
 // atrybuty proste
  
}

lub

Towar { 
   Kategoria k;
   // obiektowe
}

Sztywne dziedziczenie dla prowadzenia grup towarów / klientów / whatever tylko w szkole wygląda dobrze, ale zabija w profesjonalnym programowaniu bazodanowym

W takim razie zastosuję taką kompozycję jaką napisałeś, dzięki!

0
ZrobieDobrze napisał(a):
Wiktor89Bdg napisał(a):

Moim celem jest napisanie aplikacji służącej do transportu gdzie paczka będzie posiadać listę produktów, które mogą potrzebować różnych warunków transportu. Klasy są dość podobne i różnią się 1-3 atrybutami.

Zamiast szkolnego dziedziczenia SzczegółowyTowar : AbststrakcyjnyTowar (relacja jest)

proponuję relację ma

Towar {
  String atrybut1;
 // atrybuty proste
  
}

lub

Towar { 
   Kategoria k;
   // obiektowe
}

Sztywne dziedziczenie dla prowadzenia grup towarów / klientów / whatever tylko w szkole wygląda dobrze, ale zabija w profesjonalnym programowaniu bazodanowym

Próbuję napisać tę kompozycję i póki co wymyśliłem coś takiego, że kategoria to obiekt w relacji 1 do 1 z obiektem produkt, która posiada pola wszystkich obiektów które miały być dziedziczone, a podczas inicjalizacji uzupełnia się tylko pola dla danej kategorii. Czy mógłbyś mi podpowiedzieć czy takie coś ma sens? // Edit: Po namyślę ograniczę się do jak najprostszej implementacji produkt kategoria w relacji 1 do 1, w której kategoria zamiast enumów będzie posiadać pola string do uzupełnienia

0
Wiktor89Bdg napisał(a):

Próbuję napisać tę kompozycję i póki co wymyśliłem coś takiego, że kategoria to obiekt w relacji 1 do 1 z obiektem produkt, która posiada pola wszystkich obiektów które miały być dziedziczone, a podczas inicjalizacji uzupełnia się tylko pola dla danej kategorii. Czy mógłbyś mi podpowiedzieć czy takie coś ma sens?

Kategoria 1:1 ? Coś mi świta, tylko że to już nie jest kategoria.

Przemycasz znów implementację wielotabelową (table per type), i łączysz w jednym dwie koncepcje: pola dodatkowe i jeden dystynktywny atrybut
(skomplikowane już gadamy)

Jak mowa o RBD musimy zawiesić część swoich doświadczeń z wysokiej jakości OOP. Na styku nigdy nie było, nie jest i nie będzie idealnie, różnica paradygmatów.

Moja 'Kategoria to aż i tylko taki słownik "Hej, ja jestem produktem żywieniowym", "hej, ja higienicznym"', właściwie trudno tu wymyśleć więce niż jedno pole "Nazwa kategorii"

class Kategoria {
   String nazwa
   // bebechy pod JPA, Id itd ... 
}

h = new Kategoria("Higienicze")

Więc zawieszając swoją wiedzę o OOP (sorry, Winnetou, ale biznes is biznes), ja bym poszedł
a) jeden atrybut dystynktywny, Strig lub w/w dyskutowana obiektowa kategoria (ładne z poziomu kluczy RBD, przy okazji zobacz komu się bardziej kłaniamy, obiektom czy bazie)
b) w atrybuty proste dla pól dodatkowych (pewnie jakieś nieco anonimowe, uzyskujące interpretację po podaniu kategorii, najbezpieczniej String)
czyli String attribute1 -> uzyskuje interpretację Nr zezwolenia MZ dla medycznych, jakąś tam dla Higienicznych
Strig attribute2
Strig attribute3

W ogole KOD SYSTEMU o jakim myślę, nie ma wiedzy o Higienicznych, jest to jedna z możliwych wartości w bazie.

Mogę się mylić, gdyby - wracam do punktu wyjścia - podtypy się różniły mocno, i trzeba było silnie to wyrazić - zamrażając system do niemożliwości handlowania Warzywami. Być może robimy system TYLKO dla hurtowni leków, której nie wolno handlować czym innym ...

że ja sympatyzuję mocno ku otwartemu systemowi do wszystkich produktów, to nie znaczy, że jest to jedyne.
... i znów zataczając koło
gdyby jednak po mojemu to

Towar {
 pola stałe ...
 
 String atrybut1;
 String atrybut2;
 String atrybut3;
   
}
class Kategoria {
  String nazwa // Medyczne
  // bebechy pod JPA, Id itd ... 

  String attr1Caption ; //  'Nr zez min zdrowia'
  String attr2Caption ; //  'ble ble'
  String attr3Caption ; //  'bla bla'
}

Za taki design nigdy nie dostanę uścisku ręki na Katedrze OOP, ale wzbudzę entuzjazm w Instytucie RBD

0
Towar {
 pola stałe ...
 
 String atrybut1;
 String atrybut2;
 String atrybut3;
   
}
class Kategoria {
  String nazwa // Medyczne
  // bebechy pod JPA, Id itd ... 

  String attr1Caption ; //  'Nr zez min zdrowia'
  String attr2Caption ; //  'ble ble'
  String attr3Caption ; //  'bla bla'
}

Za taki design nigdy nie dostanę uścisku ręki na Katedrze OOP, ale wzbudzę entuzjazm w Instytucie RBD

napisz proszę w jaki sposób te 2 klasy się ze sobą łączą?

Właśnie coś mi nie pasowało z tą kategorią 1:1 bo przesunąłbym po prostu dziedziczenie w inne miejsce.
Próbuję coś z tego napisać, ale nie rozumiem, bo jeśli w kategorii jest Id a nie jest obiektem w relacji to co "ma" kategorię? Czy w tym wypadku kategoria "ma" produkt, a wtedy w obiekcie powiedzmy "kontener do transportu" powinny się znajdować np 3 hashsety z kategoriami - jeden dla higienicznych, drugi dla medycznych itd...

1

@Wiktor89Bdg:

Mój pośpiech

Oczywiście

Towar {
 pola stałe ...

 Kategoria kat;
 
 String atrybut1;
 String atrybut2;
 String atrybut3;
   
}

i Kategora bez zmian.

Znów, nie pokazuj tego na konkursie najpiękniejszego OOP.
jest to obiektowo zrecz biorą prymitywne.

Kategoria ma tu dwie role
a) jest Kategorią (zgodnie z OOP i RBD)
b) dostarcza środków ku interpretacji "anonimowych" pól zapasowych, gdy je skonfigurujemy zw z Kategorią (np "nr zez Min Zdrowia"), czy nie jest czyste dla wykładowców ani OOP ani RBD, ale to jest praktyka realnego programowania elastycznych systemów dla firm

0

dokładnie o praktykę realnego programowania elastycznych systemów dla firm mi chodziło :D dzięki wielkie!

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