как внедрить реализацию JpaRepository - PullRequest
0 голосов
/ 09 марта 2020

Я хочу использовать метод a из UserRepository в UserService, но вместо своей пользовательской реализации я получаю jpaRepository, как мне написать классы для его получения?

Репозиторий:

@Repository
public interface UserRepository<UserEntity extends EntityInterface,Long> extends JpaRepository<UserEntity,Long> {
    Optional<UserEntity> findUserByLogin(String login);
}

CrudAbstractService с методом обобщений:

public abstract class CrudAbstractService<ENTITY extends EntityInterface, DTO extends DTOInterface> {
    protected final JpaRepository<ENTITY, Long> jpaRepository;
    protected final Validator<DTO> validator;
    protected final MapperInterface<ENTITY, DTO> mapper;
    private Class<ENTITY> entityClazz;

    public CrudAbstractService(JpaRepository<ENTITY, Long> jpaRepository,
                               Validator<DTO> validator, MapperInterface<ENTITY, DTO> mapper) {
        this.jpaRepository = jpaRepository;
        this.validator = validator;
        this.mapper = mapper;
    }

    public Iterable<DTO> findAll() {
        List<ENTITY> allEntities = jpaRepository.findAll();
        if (allEntities == null) {
            throw new EntityNotFound(entityClazz);
        }
        List<DTO> mappedDTOs = mapper.toDTOs(allEntities);
        return mappedDTOs;
    }

    public void delete(DTO dto) {
        validator.validate(dto);
        ENTITY entity = mapper.toEntity(dto);
        jpaRepository.delete(entity);
    }

    public DTO save(DTO dto) {
        validator.validate(dto);
        ENTITY entity = mapper.toEntity(dto);
        ENTITY save = jpaRepository.save(entity);
        if (save == null) {
            throw new EntityNotFound(entityClazz);
        }
        DTO mappedDTO = mapper.toDTO(save);
        return mappedDTO;
    }

}

Реализация CrudUserService, я хочу добавить UserRepository вместо JpaRepository:

@Service
public class UserService extends CrudAbstractService<UserEntity,UserDTO> {

    private MapperInterface<LectureEntity,LectureDTO> lectureMapper;

    public UserService(UserRepository<UserEntity, Long> jpaRepository,
                       Validator<UserDTO> validator, MapperInterface<UserEntity, UserDTO> mapper,
                       MapperInterface<LectureEntity,LectureDTO> lectureMapper) {
        super(jpaRepository, validator, mapper);
        this.lectureMapper = lectureMapper;
    }


    public UserDTO findUserByLogin(String login) {
        if (login == null) {
            throw new UserNotFoundException();
        }
//Here i want use UserRepository method instead of JpaRepository. 
        Optional<UserEntity> userByLogin = jpaRepository.findUserByLogin(login);
        UserEntity userEntity = userByLogin.orElseThrow(UserNotFoundException::new);
        List<LectureEntity> reservations = userEntity.getReservations();
        List<LectureDTO> lectureDTOS = lectureMapper.toDTOs(reservations);
        UserDTO userDTO = mapper.toDTO(userEntity);
        userDTO.setLectures(lectureDTOS);
        return userDTO;
    }
}

1 Ответ

0 голосов
/ 09 марта 2020

Я думаю, что вам не нужно делать ваш интерфейс репозитория универсальным c.
Итак, замените это:

@Repository
public interface UserRepository<UserEntity extends EntityInterface,Long> extends JpaRepository<UserEntity,Long> {
    Optional<UserEntity> findUserByLogin(String login);
}

на это:

@Repository
public interface UserRepository extends JpaRepository<UserEntity,Long> {
    Optional<UserEntity> findUserByLogin(String login);
}

И используйте его в своем сервисе:

@Service
public class UserService extends CrudAbstractService<UserEntity,UserDTO> {

    private MapperInterface<LectureEntity,LectureDTO> lectureMapper;

    public UserService(UserRepository jpaRepository,
                       Validator<UserDTO> validator, MapperInterface<UserEntity, UserDTO> mapper,
                       MapperInterface<LectureEntity,LectureDTO> lectureMapper) {
        super(jpaRepository, validator, mapper);
        this.lectureMapper = lectureMapper;
    }
}

Если вам нужно сопоставить ваши сущности с DTO, вы можете попробовать использовать JPA-проекции

В отношении создания исключения в findAll() - на мой взгляд, это не очень хорошая идея. Вероятно, вам следует вернуть только пустой список и позволить клиентам вашего класса решать, что делать в случае пропажи объектов.

Также в вашем случае я бы старался избегать использования абстрактных классов и наследования и использовать вместо этого композицию. Наследование против композиции: как выбрать и Почему я должен предпочесть композицию наследованию?

...