CrudRepository, a InMemoryRepository

Odpowiedz Nowy wątek
2019-04-30 11:24
0

Cześć, mam pewien problem, otóż postanowiłem operować w testach na bazie InMemory - jest to HashMap'a. Na "produkcji" będzie to natomiast Postgre odpalony na Spring Data z JpaRepository. No i teraz mam problem jak zrobić to tak żeby mieć jeden wspólny interfejs dla takich Repo żebym mógł sobie stosować DI w zależności od tego czy chcę w tej chwili działać na mojej HashMapie (testy), czy Postgre ("produkcja"). Mogę po prostu na interfejsie InMemory wrzucić sobie w extends JpaRepository, ale wtedy moja klasa, która to implementuje (tam mam tworzenie HashMapy itp.) będzie musiała zaimplementować wszystkie metody tego interfejsu, a to nie jest mi w ogóle potrzebne... Jest możliwość jakiegoś ładnego obejścia tego?

Z góry dzięki.

Pozostało 580 znaków

2019-04-30 11:34
0

Ja robię często np tak:
Mam interfejs ${nazwa_agregatu}Repository, który posiada wszystkie metody, których potrzebuję.
Tworzę implementację InMemory{$nazwa_agregatu}Repository z implementacją in memory.
Tworzę implementację SpringData{$nazwa_agragatu}Repository, która posiada zależność do interfejsu rozszerzającego interfejs JpaRepository i robię to na zasadzie delegacji

Pozostało 580 znaków

2019-04-30 11:52
0

Czyli wygląda to jakoś tak:

interface SampleRepository {
    Sample save(Sample sample);
    Sample get(Long id);
}
class InMemorySampleRepository implements SampleRepository {
    HashMap<ID, Sample> samples = new HashMap<>();
    //implementacje
}
interface SampleJpaRepository extends JpaRepository<Sample, Long> {

}
class SpringDataSampleRepository implements SampleRepository {
    private SampleJpaRepository sampleRepository;
    //implementacje SampleRepo
}

Czy źle zrozumiałem?

edytowany 1x, ostatnio: weiss, 2019-04-30 11:53
Tak właśnie robię dosyć często - pustypawel 2019-04-30 13:15
Dodam tylko jeszcze, że interfejsu rozszerzającego Spring Data (np JpaRepository) nie nazywam *Repository, a Dao :) - pustypawel 2019-04-30 13:21

Pozostało 580 znaków

2019-04-30 11:59
0
weiss napisał(a):

Mogę po prostu na interfejsie InMemory wrzucić sobie w extends JpaRepository, ale wtedy moja klasa, która to implementuje (tam mam tworzenie HashMapy itp.) będzie musiała zaimplementować wszystkie metody tego interfejsu, a to nie jest mi w ogóle potrzebne...

A w czym Ci to przeszkadza? Klikasz w IDE żeby Ci wygenerował metody i zostawiasz tak jak jest. Niech zwracają nulle. Dopóki z nich nie korzystasz nie ma to znaczenia.

Robię podobnie jak kolega wyżej opisał.

public interface UserRepository extends CrudRepository<User, Long> { }

public class UserDataProvider implements UserRepository {
// tutaj lista, mapa i nadpisanie tych metod, ktore uzywam
}

public UserService(UserRepository userRepository) { }

Pozostało 580 znaków

2019-04-30 12:08
0

@kkojot:
Czyli "produkcyjnie" korzystasz tylko z interfejsu, który extenduje CrudRepository, a ta InMemoryDB to jest właśnie UserDataProvider, który ma w sobie np. HashMape i działania na niej?

Dokładnie tak. - kkojot 2019-04-30 12:09
@kkojot A co do sytuacji, gdy mam te metody CrudRepo, np. save (ona zwraca S extends Sample), a więc muszę przy returnie robić return (S) samples.put(s.getUuid(), sample)? Bez rzutowania chyba tutaj się nie obędzie? - weiss 2019-04-30 12:15
możesz dać po prostu return sample. - kkojot 2019-04-30 12:52

Pozostało 580 znaków

2019-04-30 12:22
0

A co do sytuacji, gdy mam te metody CrudRepo, np. save (...)

Nie powinieneś mieć czegoś takiego jak CrudRepository - repozytorium powinno być związane z domeną Twojej aplikacji, więc takie CrudRepository jest odpowiednikiem CrudService czy GenericDTO, przez co przeważnie nie ma sensu.

Z jakiegoś powodu ludzie na ogół bez problemu dostrzegają problemy w projektowaniu AbstractService, lecz radośnie już tworzą AbstractRepository.

http://commitandrun.pl/2016/0[...]potrzebny_wzorzec_projektowy/


edytowany 5x, ostatnio: Patryk27, 2019-04-30 12:26

Pozostało 580 znaków

2019-04-30 12:28
0

CrudRepository to akurat nazwa interfejsu Spring Data, nie moja. Natomiast mówisz tu o tym, że każdy moduł powinien mieć swoje Repozytorium, które ma swoje metody, bo niektóre moduły potrzebują metod typu archiwizowanie np., a inne już nie, tak?

Pozostało 580 znaków

2019-04-30 12:31
0

to akurat nazwa interfejsu Spring Data, nie moja.

Ach, mea culpa - za szybko wleciałem w wątek bez spojrzenia na kontekst :-)

Natomiast mówisz tu o tym, że każdy moduł powinien mieć swoje Repozytorium, które ma swoje metody, bo niektóre moduły potrzebują metod typu archiwizowanie np., a inne już nie, tak?

W gruncie rzeczy tak.


Pozostało 580 znaków

2019-04-30 12:57
1

@kkojot:
W ten deseń?

class AccountInMemoryRepository implements AccountRepository {
HashMap<UUID, Account> accounts = new HashMap<>();

    @Override
    public <S extends Account> S save(S s) {
        accounts.put(s.getUuid(), s);
        return s;
    }
}

@Patryk27
nie ma sprawy, ale link przydatny :D

Dzięki wielkie wszystkim, każda odpowiedź nakreśliła mi jak to ma wyglądać obecnie.

edytowany 1x, ostatnio: weiss, 2019-04-30 13:03
Tak, jest ok. - kkojot 2019-04-30 13:07

Pozostało 580 znaków

2019-05-01 16:42
0

Jeśli już korzystasz że springa wystarczy, że dodasz na class pary zależność do bazy h2 (in memory) I to prakrycznie wszystko. Musisz jeszcze utworzyć dwa pliki aplication.properties dla DEV PROD, albo TEST i zdefiniować tam datasource. Wszystko za darmo.

Pozostało 580 znaków

2019-05-01 20:02
0

Tak i po to właśnie piszę takie AccountInMemoryRepository jak OP wyżej podał, żeby móc szybko testować logikę biznesową bez Springa i jednocześnie uniezależnić ją od niego.

Pozostało 580 znaków

Odpowiedz
Liczba odpowiedzi na stronę

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