인프런 커뮤니티 질문&답변

김도연님의 프로필 이미지
김도연

작성한 질문수

실전! Querydsl

조회 API 컨트롤러 개발

No default constructor found;

작성

·

4.6K

0

안녕하세요!

김영한 강사님의 강의를 들으며 제 프로젝트에 맞춰서 강사님 코드를 클론 코딩해서 공부를 하던 중 하단과 같은 오류가 떠서 문의드립니다.

 

Error creating bean with name 'likeApiController' defined in file [/Users/gimnayeon/Desktop/GreenProject/GrinGreen/out/production/classes/com/grin/GrinGreen/api/LikeApiController.class]: Unsatisfied dependency expressed through constructor parameter 0; nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'likeService' defined in file [/Users/gimnayeon/Desktop/GreenProject/GrinGreen/out/production/classes/com/grin/GrinGreen/service/LikeService.class]: Unsatisfied dependency expressed through constructor parameter 1; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'businessRepository' defined in file [/Users/gimnayeon/Desktop/GreenProject/GrinGreen/out/production/classes/com/grin/GrinGreen/repository/BusinessRepository.class]: Instantiation of bean failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [com.grin.GrinGreen.repository.BusinessRepository]: No default constructor found; nested exception is java.lang.NoSuchMethodException: com.grin.GrinGreen.repository.BusinessRepository.<init>()

 

오류 그대로 기본 생성자가 없다는 거 같은데 제가 아직 부족해서 그런지 아무리 찾아봐도 어디서 문제인지 모르겠어서요.. 도움 부탁드립니다..

 

저는 멤버 가입 후 그 멤버로 업체를 만들어서 업체 목록을 조회를 하려고 했습니다!

BusinessSearchCondition

@Data
public class BusinessSearchCondition {

    private String businessName;

}

BusinessDto

@Data
public class BusinessDto {
    private Long business_id;
    private String businessName;

    @QueryProjection
    public BusinessDto(Long business_id, String businessName) {
        this.business_id = business_id;
        this.businessName = businessName;
    }
}

InitBusiness

@Profile("local")
@Component
@RequiredArgsConstructor
public class InitBusiness {

    private final InitBusinessService initBusinessService;

    @PostConstruct
    public void init() {
        initBusinessService.init();
    }
    @Component
    static class InitBusinessService {
        @PersistenceContext
        EntityManager em;
        private final MemberService memberService;
        private final BusinessService businessService;

        InitBusinessService(MemberService memberService, BusinessService businessService) {
            this.memberService = memberService;
            this.businessService = businessService;
        }


        @Transactional
        public void init() {

            Member member = new Member();
            member.setNickname("test");
            member.setMail("test@test.com");
            member.setPassword("test1234!");
            member.setMember_type("B");
            member.setMember_status("J");
            member.setHint_password("hint_01");
            member.setAnswer_password("answer");
            member.setUpdated_at(now());
            member.setCreated_at(now());

            String memberJoin = memberService.join(member);

            for (int i = 0; i < 100; i++) {
                Business business = new Business();
                business.setBusinessName("테스트밥집"+i);
                business.setHomepage("test" + i + ".com");
                business.setPhone("010-1234-5678");
                business.setAddress("제주특별자치도 제주시 첨단로 242");
                business.setLng((float) 33.450701);
                business.setLat((float) 126.570667);
                business.setCreated_at(now());
                business.setUpdated_at(now());
                business.setMember(member);

                String businessJoin = businessService.join(business);
            }
        }
    }
}

MemberService

@Transactional
public String join(Member member){
    //비밀번호 암호화 후 레포지토리에 넘기기
    String encodedPassword = passwordEncoder.encode(member.getPassword());
    member.setPassword(encodedPassword);

    validateDuplicateMember(member);//중복회원검증
    memberRepository.save(member);
    return member.getMail();
}

BusinessService

/** 업체생성 **/
@Transactional
public String join(Business business){
    validateDuplicateBusiness(business);//중복회원검증
    log.info("business {}", business);
    businessRepository.save(business);
    return business.getBusinessName();
}

BusinessRepository

@Repository
@RequiredArgsConstructor
public class BusinessRepository {

    private final EntityManager em;
    private final JPAQueryFactory queryFactory;

    public BusinessRepository(EntityManager em) {
        this.em = em;
        this.queryFactory = new JPAQueryFactory(em);
    }
public List<BusinessDto> search(BusinessSearchCondition condition){
        return queryFactory
                .select(new QBusinessDto(
                        business.id,
                        business.businessName))
                .from(business)
                .where(businessNameEq(condition.getBusinessName()))
                .fetch();
    }
    private BooleanExpression businessNameEq(String businessName) {
        return isEmpty(businessName) ? null : business.businessName.eq(businessName);
    }
}

 

 

 

 

 

 

답변 1

0

안녕하세요. 김도연님, 공식 서포터즈 OMG입니다.

com.grin.GrinGreen.repository.BusinessRepository 리포지토리 위에

@NoArgsConstructor를 선언하여 확인해주세요

 

감사합니다.

김도연님의 프로필 이미지
김도연
질문자

안녕하세요!

말씀하신 방법은 이미 해봤는데 하단 이미지처럼 빨간 줄이 그어지며 Variable 'queryFactory' might not have been initialized , java: variable em might not have been initialized 오류가 뜹니다. image

@NoArgs는 지우고,

아래를 참고하여 별도의 스프링 설정파일에서 JpaQueryFactory를 스프링 빈으로 등록하고,

BusinessRepository에서 JpaQueryFactory를 주입 받아서 사용해보시겠어요?

 

image

BusinessRepository의 생성자는 지우고, EntityManager도 지워서

JpaQueryFactory만 주입 받아서 확인해주세요

@Repository
@RequiredArgsConstructor
public class BusinessRepository {

    private final JPAQueryFactory queryFactory;

   
public List<BusinessDto> search(BusinessSearchCondition condition){
        return queryFactory
                .select(new QBusinessDto(
                        business.id,
                        business.businessName))
                .from(business)
                .where(businessNameEq(condition.getBusinessName()))
                .fetch();
    }
    private BooleanExpression businessNameEq(String businessName) {
        return isEmpty(businessName) ? null : business.businessName.eq(businessName);
    }
}
김도연님의 프로필 이미지
김도연
질문자

안녕하세요!!

와 해결됐습니다ㅠ.ㅠ 제가 지금 기존의 비즈니스 레포지토리는 jpa레포지토리를 상속 받은 상태가 아니라서 별도의 레포지토리로 분리해서 테스트 해봤는데 잘 됩니다!! 혹시 따로 빈 등록을 해야 했던 이유를 알 수 있을까요?강의에서는 빈 등록을 안 해도 됐던 걸로 공부를 했었어서요..

강의에서는 직접 new연산으로 테스트 마다 new로 생성해서 오류가 없었을 것 같아요

김도연님의 프로필 이미지
김도연
질문자

아하 그렇군요...또 배워갑니다. 늦은 시간에 친절한 답변 정말 감사합니다!!!

김도연님의 프로필 이미지
김도연

작성한 질문수

질문하기