Я играю с приложением Spring с двумя контроллерами и двумя службами, которые управляют связанными объектами, и я хотел бы избежать дублирования кода. У меня, например, есть класс Person
с его PersonRepository
@Entity
@Inheritance(strategy = InheritanceType.JOINED)
public class Person {
@Id
Long id;
String name;
String surname;
}
И его ребенок User
со своим UserRepository
@Entity
@Inheritance(strategy = InheritanceType.JOINED)
public class User extends Person {
String login;
String password;
}
У меня есть простой сервис Person с бизнес-логикой:
@Service
public class PersonService {
@Autowired
PersonRepository repo;
public Iterable<Person> getAll() {
// Busines Logic
return repo.findAll();
}
}
Есть ли способ создать UserService, расширяющий или проксирующий PersonService и реализующий какой-то репозиторий, «скрывающий»? Что-то вроде этого:
@Service
public class UserService extends PersonService {
@Autowired
UserRepository repo;
}
это, очевидно, дает эту ошибку: Несоответствие типов: невозможно преобразовать Iterable<Person> в Iterable<User> с помощью такого контроллера.
@RestController
@RequestMapping(value = "/test", produces = MediaType.APPLICATION_JSON_VALUE)
public class DemoController {
@Autowired
UserService service;
@GetMapping
public void items() {
Iterable<User> persons = service.getAll();
return;
}
}
Попробуйте следующую структуру:
Общий сервис и репозиторий:
@NoRepositoryBean
public interface PersonRepository<T> extends JpaRepository<T, Long> {
}
public class PersonService<T extends Person> {
protected PersonRepository<T> repository;
public <R extends PersonRepository<T>> PersonService(R repository) {
this.repository = repository;
}
public Iterable<T> getAll() {
return repository.findAll();
}
}
Для сущности пользователя:
public interface UserRepository extends PersonRepository<User> {
}
@Service
public class UserService extends PersonService<User> {
public UserService(UserRepository repository) {
super(repository);
}
public void additionalMethod() {
User user = repository.getOne(1L);
}
}
И я добавил сущность компании по примеру сущности пользователя:
public interface CompanyRepository extends PersonRepository<Company> {
}
@Service
public class CompanyService extends PersonService<Company> {
public CompanyService(CompanyRepository repository) {
super(repository);
}
public void additionalMethod() {
Optional<Company> company = repository.findById(1L);
}
}