Mamy standardowy serwis i repozytorium
@Service
class TestService {
private final TestRepository testRepository;
@Autowired
TestService(TestRepository testRepository) {
this.testRepository = testRepository;
}
//...
}
@Repository
interface TestRepository extends CrudRepository<TestEntity, Long> {
}
@Entity
class TestEntity {
@Id
private Long id;
//...
}
Chcę teraz podmienić implementację TestRepository
na własną (np. na potrzeby testów). Mam coś takiego:
class InMemoryCrudRepository<T, ID> implements CrudRepository<T, ID> {
private final Map<ID, T> repository = new HashMap<>();
@Override
public <S extends T> S save(S s) {
return s;
}
//...
}
Chodzi o to, żeby "podstawić" InMemoryCrudRepository
pod TestRepository
.
class TestServiceTest {
private final TestService testService;
TestServiceTest() {
testService = new TestService(new InMemoryCrudRepository<TestEntity, Long>()); //to się oczywiście nie skompiluje
}
}
Do konstruktora muszę przekazać coś, co:
- Pochodzi od
TestRepository
- Rozszerza
InMemoryCrudRepository
Mój pomysł:
class InMemoryTestRepository<T, ID> extends InMemoryCrudRepository<T, ID> implements TestRepository {
}
Niestety dostaję błąd:
Error:(3, 1) java: org.springframework.data.repository.CrudRepository cannot be inherited with different arguments: <com.example.demo.TestEntity,java.lang.Long> and <T,ID>
Rozwiązaniem jest sparametryzowanie TestRepository
@Repository
interface TestRepository<X, Y> extends CrudRepository<X, Y> {
}
ale wtedy w serwisie musiałbym podać typy, żeby dało się tego normalnie używać.
@Service
class TestService {
private final TestRepository<TestEntity, Long> testRepository;
//było private final TestRepository testRepository;
}
A tego bym nie chciał. Jest jakiś inny sposób, żeby w serwisie podmienić implementację TestRepository
? (o ile to możliwe)
jakieś
rozwiązanie :D