CrudRepository, a InMemoryRepository

CrudRepository, a InMemoryRepository
WE
  • Rejestracja:około 7 lat
  • Ostatnio:ponad 5 lat
  • Postów:53
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.

PU
  • Rejestracja:ponad 9 lat
  • Ostatnio:5 miesięcy
  • Postów:59
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

WE
  • Rejestracja:około 7 lat
  • Ostatnio:ponad 5 lat
  • Postów:53
0

Czyli wygląda to jakoś tak:

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

Czy źle zrozumiałem?

edytowany 1x, ostatnio: weiss
PU
Tak właśnie robię dosyć często
PU
Dodam tylko jeszcze, że interfejsu rozszerzającego Spring Data (np JpaRepository) nie nazywam *Repository, a Dao :)
KK
  • Rejestracja:prawie 17 lat
  • Ostatnio:14 dni
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ł.

Kopiuj
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) { }

WE
  • Rejestracja:około 7 lat
  • Ostatnio:ponad 5 lat
  • Postów:53
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?

KK
Dokładnie tak.
WE
@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?
KK
możesz dać po prostu return sample.
Patryk27
Moderator
  • Rejestracja:ponad 17 lat
  • Ostatnio:prawie 2 lata
  • Lokalizacja:Wrocław
  • Postów:13042
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/05/11/Repozytorium_najbardziej_niepotrzebny_wzorzec_projektowy/


edytowany 5x, ostatnio: Patryk27
WE
  • Rejestracja:około 7 lat
  • Ostatnio:ponad 5 lat
  • Postów:53
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?

Patryk27
Moderator
  • Rejestracja:ponad 17 lat
  • Ostatnio:prawie 2 lata
  • Lokalizacja:Wrocław
  • Postów:13042
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.


WE
  • Rejestracja:około 7 lat
  • Ostatnio:ponad 5 lat
  • Postów:53
1

@kkojot:
W ten deseń?

Kopiuj
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
KK
Tak, jest ok.
BA
  • Rejestracja:około 13 lat
  • Ostatnio:ponad 2 lata
  • Lokalizacja:Wrocław
  • Postów:259
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.

KK
  • Rejestracja:prawie 17 lat
  • Ostatnio:14 dni
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.


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.