#java #spring
#java #spring
Вопрос:
Я играю с приложением Spring с 2 контроллерами и 2 службами, которые управляют связанными объектами, и я хотел бы избежать дублирования кода. У меня есть, например 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;
}
У меня есть простой пользовательский сервис с бизнес-логикой:
@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;
}
это, очевидно, приводит к этой ошибке:
Несоответствие типов: невозможно преобразовать из итеративного <Person> в итеративный <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;
}
}
Ответ №1:
Попробуйте следующую структуру:
Общий сервис и репозиторий:
@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();
}
}
Для объекта User:
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);
}
}
И я добавил объект Company по примеру объекта User:
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);
}
}