[プロジェクト問題解決]OAuth 2 Googleログインエラー(問題:#10,#11)


GitHubプロジェクトキット
https://github.com/Unicorn-Finder/UnicornFinder/issues
Issue : #10
問題の状況
:OAuth 2でGoogleログインしようとしたが、ログイン画面で再びメイン画面に移行できない場合があった.
(下の画面からメイン画面に移行しない)

エラーメッセージ
  • EmptyResultDataAccessException: No entity found for query
  • NoResultException: No entity found for query
  • エラーメッセージから見ると、両方のエラーは쿼리에 대한 엔티티를 찾을수 없다です.
    ソリューション
    1.戻り値のチェック
    ログイン中にクエリーを送信する部分はMemberRepositoryfindByEmailの方法しかなく、この部分は疑わしい.
    //중복 이메일 검색
    public Optional<Member> findByEmail(String email) {
         Member member = em.createQuery("select m from Member m where m.email = :email", Member.class)
               .setParameter("email", email)
               .getSingleResult();
         return Optional.ofNullable(member);
    }
    쿼리에 대한 값을 찾을수없다と言っていますが、そのうちの1つに問題があると思います.
    エラー作成
  • JPQL
  • 結果値
  • は、正しくない
  • を返します.
    この2つの理由では、結果値が正しく返されていないことに集中します.
    Google検索でgetSingleResult()は、結果がnullの場合、nullを個別に処理するコードを記述する必要があることを発見しました.
    SpringDataJPAの実施者は、Jpa Repositoryを実施した簡単なJpa Repositoryである.
    2.Spring Data JPAの実装の検証
    現在プロジェクトはSpringBootとJPAで行われており、私が参考にしたOAuth 2ログインはSpring Data JPAで実現されているので、repositoryはとても簡単です.
    データjpaはよくわかりませんが、インタフェースを書くだけで、勝手に実装体に入れることができることを知っています.私のRepositoryとデータjpaの実装体が何が違うのか、私は何を間違っているのかを見たいです.
    Google検索でSpring DataJPAの実装体が単純JPA Repositoryであることがわかり、IntelliJでコードを見ました.


    このように、この下に様々な方法が現れています.中にはfindByIdも調べました.
    具体的には、SimpleJpa Repositoryに@Transactionalがあるため、問題11の解決が容易である.
    @Override
    	public Optional<T> findById(ID id) {
    		Assert.notNull(id, ID_MUST_NOT_BE_NULL);
    		Class<T> domainType = getDomainClass();
            ...생략...
            Map<String, Object> hints = new HashMap<>();
    		getQueryHints().withFetchGraphs(em).forEach(hints::put);
    
    		return Optional.ofNullable(type == null ? em.find(domainType, id, hints) : em.find(domainType, id, type, hints));
    	}
    Data Jpaはreturnでnull処理を行った.これを参考に誤りを修正してみます.
    しかし、探しているうちに、より簡単な解決方法が発見された.
    3.getResultList()に戻る
    Data Jpaと同様に、getSingleResult()ではなくオプションを使用してnullチェックを実現することは、より読み取りやすく、null値を含む意味があるので、それを参照して実現します.
    //중복 이메일 검색
        public Optional<Member> findByEmail(String email){
            List<Member> member = em.createQuery("select m from Member m where m.email = :email", Member.class)
                    .setParameter("email", email)
                    .getResultList();
            return member.stream().findAny();
        }
    結果
    以下のようにログインが良好であることがわかります.

    結果はよく出てきて、間違いを探しているうちに、OptionとStreamの部分が弱いことに気づきました.この部分も勉强して整理しておきます.