CrudRepository, a InMemoryRepository

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.

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

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?

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

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/

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?

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.

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.

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.

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.

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