본문 바로가기

카테고리 없음

TiL: CH 3 일정 관리 앱 Develop트러블 슈팅?

  • 1. Jpa활성화(코드스니펫)
더보기

문제: 코드 스니펫을 보고 타이핑 ->안보고 작성할 정도에 공부는 필요

@Getter
@MappedSuperclass
@EntityListeners(AuditingEntityListener.class) // JPA Auditing 활성화
public abstract class BaseEntity {
    @CreatedDate
    @Column(updatable = false)
    private LocalDateTime createdAt;

    @Setter
    @LastModifiedDate  // 수정 시간 자동 업데이트
    private LocalDateTime updatedAt;
}
@EnableJpaAuditing
@SpringBootApplication
public class ScheduleApplication {

    public static void main(String[] args) {
        SpringApplication.run(ScheduleApplication.class, args);
    }

}
  • 2. filter부분& Webconfig(코드스니펫)
더보기

문제: 코드 스니펫을 보고 타이핑 ->안보고 작성할 정도에 공부는 필요

@Configuration
public class WebConfig {
    @Bean
    public FilterRegistrationBean loginFilter(){
        FilterRegistrationBean<Filter> filterRegistrationBean= new FilterRegistrationBean<>();
        filterRegistrationBean.setFilter(new LoginFilter());
        filterRegistrationBean.setOrder(1);
        filterRegistrationBean.addUrlPatterns("/*");
        return filterRegistrationBean;
    }
}
package com.example.schedule.login;

import jakarta.servlet.*;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.servlet.http.HttpSession;
import org.springframework.util.PatternMatchUtils;

import java.io.IOException;

public class LoginFilter implements Filter {
    private static final String[] whiteList={"/home/login","/home/logout","/authors"};


    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {

        HttpServletRequest httpServletRequest=(HttpServletRequest) servletRequest;
        String requestURL=httpServletRequest.getRequestURI();

        HttpServletResponse httpServletResponse=(HttpServletResponse) servletResponse;

        HttpSession httpSession=httpServletRequest.getSession(false);

        if (!IsWhiteList(requestURL)) {
            if (httpSession == null || httpSession.getAttribute(Const.LOGIN_USER) == null) {
                throw (new IOException("하기싫어요"));
            }
        }
        filterChain.doFilter(httpServletRequest,httpServletResponse);
    }
    private boolean IsWhiteList(String requestURL ){

        //보고 하자
        return PatternMatchUtils.simpleMatch(whiteList,requestURL);
    }



}
  • 3. Password(발제)
더보기

목적 : 비밀번호 설정

@Component ->"생성자 주입하면 되겠네"-> 문제가 발생x

문제:아래 코드를 보면서 작성했기 때문에 공부 필요합니다 

궁금증:Spring Security 을 사용해도 아래코드가 필요한가?

import at.favre.lib.crypto.bcrypt.BCrypt;
import org.springframework.stereotype.Component;

@Component
public class PasswordEncoder {

    public String encode(String rawPassword) {
        return BCrypt.withDefaults().hashToString(BCrypt.MIN_COST, rawPassword.toCharArray());
    }

    public boolean matches(String rawPassword, String encodedPassword) {
        BCrypt.Result result = BCrypt.verifyer().verify(rawPassword.toCharArray(), encodedPassword);
        return result.verified;
    }
}
  • 4 jqpl문(아래 블로그)
더보기

목적 : Return LoginResponseDto

검색: jpa 기본문법 구글 

 Member singleResult1 = em.createQuery("select m from Member as m where m.username = :username", Member.class)
                    .setParameter("username", "member1")
                    .getSingleResult();

 

해결법: 위 코드를 목적에 qurey문 변환,class 변환, parameter 변환

결론 :아직 미숙한  jqpl문 추가적인 공부가 필요합니다.

궁금증: jqpl문보다 더 좋은 방법이 있을지 궁금합니다.

  • 5. oneToMany(chatGpt)
더보기

문제: 동기화가 안되는 발생

해결법: chatGpt 질문: 동기화가 되지않는 문제가 발생해 원인이 뭐고 이유를 알려줘

@OneToMany(mappedBy = "schedule", cascade = CascadeType.ALL, orphanRemoval = true)

 

원인 : JPA의 변경 감지가 일어나지 않음 (하이버네이트의 1차 캐시 문제)

해결 : @OneToMany를 @OneToMany(cascade = CascadeType.ALL, orphanRemoval = true)로 변경하여 schedule 만 저장해도 자동으로 저장되도록 설정할 수도 있음.
  • mappedBy = "schedule" → 연관 관계의 주인을 Task로 설정하여, 외래 키 관리
  • cascade = CascadeType.ALL → 부모의 변경이 자식에게 자동으로 반영되도록 설정
  • orphanRemoval = true → 부모에서 제거된 자식 엔티티를 자동으로 삭제

궁금증: 하이버네이트의 1차 캐시 문제가 무엇인가? 

  • 6. page
더보기

목적 : 페이지 표현하기

해결법 : 아래코드들 참고해서 구현방식 참고한 후, 본 코드에 맞게 수정

문제: "Page<>" 자체에 이해가 부족-> "List<>"로 표현 

// Controller
@GetMapping("/users")
fun findAll(pageable: Pageable): ResponseEntity<UsersResponse> {
    val usersResponse = userService.findAllUsers(pageable)
    return ResponseEntity.ok(usersResponse)
}

// Service
fun findAllUsers(pageable: Pageable): UsersReponse {
    val findUsers = users.findAllUsersWithPaging(pageable)
    return UsersReponse.from(findUsers)
}

// Repository
fun findAllUsersWithPaging(pageable: Pageable): Page<Task>

 

Pageable pageable = PageRequest.of(pageNo, PAGE_SIZE, Sort.by(Sort.Direction.DESC, criteria));
  • 7. @NotBlank
더보기

문제: No validator could be found for constraint 'jakarta.validation.constraints.NotBlank' validating type 

'java.lang.Long'. Check configuration for 'id']

 

해결: Long에는 NotBlank가 안된다. NotLull로 해야 한다.(type이 맞지 않습니다)

해결방법: 영어 잘 읽고 1차 수정 -> 구글 검색 후 2차 수정-> ChatGpt 사용 3차 수정 ->튜터님 질문 4차 수정

 

https://velog.io/@rmswjdtn/JPA-JPQL-%EA%B8%B0%EB%B3%B8%EB%AC%B8%EB%B2%95JPA-%EA%B8%B0%EB%B3%B8%ED%8E%B8-by-%EA%B9%80%EC%98%81%ED%95%9C

 

[JPA] JPQL 기본문법(JPA 기본편 by 김영한)

JPQL 기본문법 이제까지 단순히 특정 pk값의 객체를 조회할 때 em.find()를 사용해왔습니다. 하지만 만약 조건이 더 복잡한 조회를 해야한다면 JPQL을 사용해야합니다! JPQL은 객체지향적으로 쿼리문

velog.io

https://xrabcde.github.io/pagination/

 

JPA/No offset 방식으로 페이징 성능 개선하기

offset 방식에서 no offset 방식으로 개선하는 방법과 성능 차이에 대해 알아보자

xrabcde.github.io

 

https://velog.io/@kimdy0915/JPA-Spring-Data-Jpa-Pageable%EB%A1%9C-Pagination-%EC%89%BD%EA%B2%8C-%EA%B5%AC%ED%98%84%ED%95%98%EA%B8%B0

 

[JPA] Spring Data Jpa + Pageable로 Pagination 쉽게 구현하기

이번주는 독서리뷰를 남길 수 있는 미니 프로젝트를 진행하고 있다. 리뷰 글을 특정 조건으로 뽑아서 정렬 기준을 선택하여 조회하는 기능을 구현하고자 한다.전체 리뷰글을 조회하거나, 내가

velog.io