• 카테고리

    질문 & 답변
  • 세부 분야

    백엔드

  • 해결 여부

    미해결

안녕하세요

23.03.08 11:21 작성 조회수 378

0

학습하는 분들께 도움이 되고, 더 좋은 답변을 드릴 수 있도록 질문전에 다음을 꼭 확인해주세요.

1. 강의 내용과 관련된 질문을 남겨주세요.
2. 인프런의 질문 게시판과 자주 하는 질문(링크)을 먼저 확인해주세요.
(자주 하는 질문 링크: https://bit.ly/3fX6ygx)
3. 질문 잘하기 메뉴얼(링크)을 먼저 읽어주세요.
(질문 잘하기 메뉴얼 링크: https://bit.ly/2UfeqCG)

질문 시에는 위 내용은 삭제하고 다음 내용을 남겨주세요.
=========================================
[질문 템플릿]
1. 강의 내용과 관련된 질문인가요? (예/아니오)
2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예/아니오)
3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예/아니오)

[질문 내용]
영한님 강의를 들으면서 내용을 일부 수정해서 공부를 하고 있습니다 . 세션 부분인데요 영한님 강의에서는 JPA 를 사용하지 않았지만 저는 JPA 를 사용해보았습니다.

 

하지만 계속

WARN 11252 --- [io-8080-exec-10] .w.s.m.s.DefaultHandlerExceptionResolver : Resolved [org.springframework.web.method.annotation.MethodArgumentConversionNotSupportedException: Failed to convert value of type 'java.util.Optional' to required type 'project.PointWeb.Domain.Member'; Cannot convert value of type 'java.util.Optional' to required type 'project.PointWeb.Domain.Member': no matching editors or conversion strategy found]

 

이 에러가 발생해서 고민중입니다.

Optional 이 문제인 것 같은데 어떻게 변경을 해야 할 지 모르겠습니다.

 

강의 내용을 조금 변경해서 실습을 하고 있어서 질문드릴까 고민했지만, 해결할 수 있는 방법을 찾지 못해서 질문 드립니다.... 감사합니다

답변 2

·

답변을 작성해보세요.

0

y2gcoder님의 프로필

y2gcoder

2023.03.08

안녕하세요, 작성자 님. 공식 서포터즈 y2gcoder 입니다.

일단 원인은 알고 계신 것처럼 Optional 관련 문제가 맞습니다. 그래서 보이는 부분만 보면 SessionAttribute에 넣을 때 optional 객체에서 값을 꺼내준 다음 넣으셔야 할 것 같습니다.

그리고 제 개인적으로는 2가지 중 마음에 드시는 쪽으로 수정하시는 것을 추천드립니다.

  1. MemberRepository에서 JpaRepository를 상속받고 있습니다. JpaRepository를 상속받으면 Spring Data JPA에서 자동적으로 해주는 일이 많은 대신 그만큼 제약이 있습니다. 특히 findBy~ 문들은 거의 규칙대로 작성해주셔야 합니다. findById로 해주셔야 하고, 무엇보다 findById()가 이미 있습니다.
    이를 임의로 수정하기는 것은 손해가 많습니다. JpaRepository를 상속받아서 한다면 저는 MemberRepository를 MemberJpaRepository로 이름을 변경한 후, 이에 의존하는 MemberRepository를 둘 것 같습니다.
    MemberRepository - MemberJpaRepository(기존의 MemberRepository)
    그리고나서 MemberRepository에 원하시는대로 Member findById(Long id)를 만든 뒤, 해당 메서드에서는 MemberJpaRepository 가 자동으로 만들어주는 Optional<Member> findById(Long id)로 Optional 객체를 받아온 다음, Member가 있는지 확인하고 꺼내서 리턴해주는 식으로 해줄 수 있을 것 같습니다.

    @Repository
    public class MemberRepository {
        private final MemberJpaRepository memberJpaRepository;
    
        public MemberRepository(MemberJpaRepository memberJpaRepository) {
            this.memberJpaRepository = memberJpaRepository;
        }
        
        //...생략
        
        public Member findById(Long id) {
            return memberJpaRepository.findById(id).orElseThrow(Member엔티티찾지못했을때예외);
        }
    }
    //기존 MemberRepository
    public interface MemberJpaRepository extends JpaRepository<Member, Long> {
        Optional<Member> findByMemberId(String memberId);
    
        //기존 findById 삭제
    }

     

  2. 다른 방식으로는 해당 링크처럼 MemberRepository에서 JpaRepository가 아닌 Repository로 상속받는 것입니다. 이렇게 하면 쿼리 메서드 형식만 지켜주면 자기가 원하는대로 메서드를 만드실 수 있습니다. Member findById(Long id) 로 만드실 수 있습니다. 대신 이 때는 save나 기존에 자동으로 만들어주던 것들도 임의로 만들어서 사용하셔야 합니다.

    public interface MemberRepository extends Repository<Member, Long> {
        Member findById(Long id);
        Member save(Member member);
        //...
    }

 

 


감사합니다.

작성자님의 프로필

작성자

질문자

2023.03.08

답변 진짜 감사합니다. 생각보다 엄청 친절하게 답변주셔서 감사합니다!!! 다시 해보겠습니다!!

y2gcoder님의 프로필

y2gcoder

2023.03.08

감사합니다~
파이팅입니다!

작성자님의 프로필

작성자

질문자

2023.03.10

안녕하세요 계속 시도해보다가 궁금한점이 생겨서 질문드립니다,

"SessionAttribute에 넣을 때 optional 객체에서 값을 꺼내준 다음 넣으셔야 할 것 같습니다."

 

라고 하셨는데 어떻게 값을 꺼낼수 있을까요?

y2gcoder님의 프로필

y2gcoder

2023.03.10

Optional 객체에서 값을 꺼내는 방법은

optional.orElseThrow() 나 optional.orElse(), optional.orElseGet(), optional.get() 등 다양한 방법을 지원합니다. Optional 객체에 대해서 잘 모르신다면 Java Optional 객체에 대해서 먼저 공부해보시는 것을 권해드립니다 :)

작성자님의 프로필

작성자

질문자

2023.03.10

계속 질문 드려서 죄송합니다.

Optional 자체의 값을 꺼내는 것은 알겠지만 제가 작성한 컨트롤러 코드 매개변수 내에서 optional 값을 꺼내보려고 계속 시도했는데 방법을 잘 모르겠습니다.

 

번거롭게 해드려서 죄송합니다..

y2gcoder님의 프로필

y2gcoder

2023.03.10

아닙니다~ 제가 작성자 님의 질문을 오해했습니다. 죄송합니다.

위에 올려주신 코드를 보면 SessionAttribute에 LOGIN_MEMBER를 키로 가진 value값을 Member 타입으로 꺼내오는 것으로 보입니다. 여기서 예외가 나서 올려주신 것으로 이해했고,
예외 내용이 Optional 타입을 Member 타입으로 변환할 수 없다는 것이었습니다.

그래서 저는 Session에 해당 객체를 저장할 때, Optional 객체를 그대로 넣으신 것으로 이해했고 Session에 객체를 넣을 때 Optional 객체에서 저장할 객체를 꺼내 Session 객체에 넣으셔야 한다고 답변을 드렸습니다.

혹시 Session에 해당 객체를 저장하실 때 Optional 객체를 그대로 넣으신 게 아니시란 말씀이실까요?

세션에 값을 LOGIN_MEMBER를 키로 하여 값을 넣어주는 부분의 코드를 보여주시겠습니까?

작성자님의 프로필

작성자

질문자

2023.03.10

답변 감사합니다. 제가 궁금했던 부분은 영한님은 jpa 사용 시 optional 을 주로 이용해서 member 객체를 반환하셨는데, 세션 기능 부분은 jpa 를 사용하지 않고 실습을 하셨습니다. 그래서 세션 부분에서 만약 jpa 를 사용하면 어떨지 공부하던 참에 optional 부분에서 막혔었습니다.

 

image

image

image

image

이런 식으로 코드를 짰습니다. JpaRepository 에서 optional 로 Member 를 받아서 문제가 생긴 것 같은데 Controller 에서 매개변수에 optional 로 받으려고 했는데 실패하였습니다. Contoller 부분에서 어떻게 해야 오류 없이 작동할지 고민입니다.

 

친절한 답변 정말 감사합니다!!

y2gcoder님의 프로필

y2gcoder

2023.03.10

엇 마지막 답변에서 말씀하시고자 하는 바를 이해하지 못했는데, 위에 단 답변에서 코드가 필요하다고 한 것은 Session에 Login한 Member를 저장하는 로직의 코드입니다!

위에 올려주신 코드는 원래 질문에서 올려주신 코드들과 차이가 없는 것으로 보입니다 :)

작성자님의 프로필

작성자

질문자

2023.03.10

와...해결했습니다 진짜 감사합니다 1주일 넘게 고민했었는데 덕분에 해결했습니다.. 감사합니다!!

y2gcoder님의 프로필

y2gcoder

2023.03.10

헉... 일주일이나 되셨군요!
고생많으셨습니다 ㅎㅎ
열심히 문제 해결하려고 하시는 모습이 정말 멋있습니다.
파이팅입니다!

0

Sang-Uk Lee님의 프로필

Sang-Uk Lee

2023.03.08

It seems return type of the method findByid(Long id) should be Optional(Member).

작성자님의 프로필

작성자

질문자

2023.03.10

Thank you~