本文介绍了如何注入JpaRepository的实现的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想在UserService中使用UserRepository中的方法a,但是我正在获取jpaRepository而不是我的自定义实现,我应该如何编写类来获取它?

I want to use method a from UserRepository in UserService, but I'm getting jpaRepository instead my custom implementation, how should I write classes to get it?

存储库:

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

CrudAbstractService具有泛型方法:

CrudAbstractService with generics method:

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:

Implementation of CrudUserService, there I want to inject UserRepository instead of 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;
    }
}

推荐答案

我认为您不需要使存储库接口具有通用性.
因此,替换为:

I think you don't need to make you repository interface generic.
So, replace this:

@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);
}

并在您的服务中使用它:

And use it in your service:

@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投影

If you need to map your entities to DTOs then you can try to use JPA projections

关于在 findAll()中引发异常-在我看来,这不是一个好主意.您可能应该只返回空列表,并让班级的客户决定在缺少实体的情况下该怎么做.

Regarding throwing an exception in findAll() - in my opinion, it's not a good idea. You should probably return just empty list and let the clients of your class decide what to do in case of missing entities.

在您的情况下,我也将尝试避免使用抽象类和继承,而应使用组合.继承与组成:如何选择我为什么要首选组成而不是继承?

Also in your case I would try to avoid using abstract classes and inheritance and use composition instead. Inheritance versus composition: How to choose and Why should I prefer composition over inheritance?

这篇关于如何注入JpaRepository的实现的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

09-16 23:19