본문 바로가기

Spring

(8)
@OneToMany Fetch Join 시 데이터 중복과 주의점 오늘은 JPA를 사용하면서 발생했던 OneToMany와 Fetch Join을 같이 사용할 때의 주의할 점과 발생하는 데이터 중복 해결 방법에 대해서 작성해보겠습니다. 참고자료는 김영한님의 자바 ORM 표준 JPA 프로그래밍 책입니다. 1. @OneToMany Fetch Join은 중복 데이터가 발생된다? 첫 번째로, @OneToMany 연관관계에서 Fetch Join으로 데이터를 가져오는 경우 중복 데이터가 생길 수 있습니다. 중복 데이터가 발생하는 원인은 fetch Join을 하면, 연관된 데이터를 모두 가져오기 때문에, 아래 같은 경우 team에 대해서 fetch join을 하면 Team의 레코드 개수는 6개가 될 것입니다. Team Id는 중복되지만, 연관된 Member ID는 다르기 때문에 다른 ..
Dynamic Proxy, CGLIB - Java로 인터셉터 만들어보기 AOP, Interceptor... 왜 필요할까? 애플리케이션을 개발하면서, 특정한 객체의 메소드가 호출될 때마다 로깅을 남기거나, 트랜잭션을 관리하는 등의 작업이 필요할 때가 있습니다. 이러한 작업을 위해서는 각각의 메소드에 코드를 추가해주어야 하지만, 이는 번거로운 작업입니다. 이러한 경우, 동적 프록시와 CGLIB을 이용하여 인터셉터를 구현하여, 중복 코드를 제거하고 작업을 간편하게 할 수 있습니다. 이러한 인터셉터를 구현하는 것이 대표적인 AOP라고 합니다. 비즈니스 로직과 인프라 로직을 분리하는 것이죠. 간단하게 제가 만들고 있는 웹 서버의 루트 디렉토리를 접속했을 때 index.html을 보여주는 예제를 어떻게 개선했는지 보여드리겠습니다. 주석만 살펴보면 루트로 HTTP 요청이 들어오면 ind..
Reflection과 Custom Annotation 활용기 2 - @ExceptionHandler 구현하기 안녕하세요! 오늘은 저번 포스팅에 이어서 Reflection을 좀 더 활용해본 활용기를 가져왔습니다. 이번 포스팅에서는 Spring 없이 동작하는(그러나 비슷하게 돌아가는) 제 웹 서버에서 Reflection과 Custom Annotation을 좀 더 활용해서 @ExceptionHandler 어노테이션과 그 역할을 비슷하게 구현해보았습니다. 전체적인 구현방향, 흐름은 아래와 같습니다. UserLogin 기능을 사용할 때 login이 실패하는 경우 Custom 예외를 발생시키도록 구현했다고 할 때, 어떻게 예외를 잘 분리해서 처리할까에 대한 고민을 담았다고 보시면 될 것 같습니다. Spring MVC의 예외 처리 전략과 흐름만 보면 얼핏 비슷합니다. 이 포스팅의 마지막에서는 실제 스프링의 예외처리 전략에 ..
Reflection과 Custom Annotation 활용기 1 - @RequestMapping 구현하기 커스텀 어노테이션과 Reflection은 강력한 기능으로, 프로그래머들에게 많은 편의와 유연성을 제공합니다. 이번 포스팅에서는 Java의 커스텀 어노테이션과 Reflection에 대해 알아보고, 그 활용에 대해 살펴보겠습니다. Annotation이란? 어노테이션이란 코드에 부가적인 메타데이터를 표현하는 방법으로, 컴파일러, 런타임, reflection 등에서 사용되어 코드의 동작이나 처리를 제어하거나 정보를 제공하는 기능을 수행합니다. 코드에 부가적인 메타데이터를 부여한다는 관점에서 주석과 비슷하지만, 사용 목적과 처리 시점에서 가장 큰 차이가 있습니다. 주석은 개발자 간 소통이나 혹은 작성한 코드의 이해를 돕기 위해 작성되는 반면, 어노테이션은 컴파일러, 런타임에 동작을 위한 부가적 정보를 부여하기 위..
AJAX와 Jquery로 비동기 댓글달기 웹페이지를 제작할 때, 사용자의 경험을 향상시키는 것은 매우 중요합니다. 이를 위해 AJAX와 jQuery 같은 웹 기술이 자주 사용됩니다. AJAX는 비동기적으로 서버와 통신하여 페이지를 동적으로 업데이트하는 데 사용되며, jQuery는 이를 보다 쉽게 처리할 수 있도록 도와줍니다. 이번 글에서는 AJAX와 jQuery를 사용하여, 블로그나 다른 웹페이지를 보다 동적으로 만드는 방법에 대해 살펴보려고 합니다. AJAX와 jQuery를 사용하면, 더욱 효율적이고 사용자 친화적인 웹페이지를 제작할 수 있습니다. 아래에서는 AJAX와 jQuery의 개념과 이를 사용하여 구현할 수 있는 기능에 대해 자세히 알아보도록 하겠습니다. AJAX란? AJAX는 "Asynchronous JavaScript and XML..
Mock을 이용한 Sliced Test - @WebMvcTest, @JdbcTest Spring Framework와 Sliced Test 스프링에서 테스트를 위해 @SpringBootTest를 이용하곤 합니다. 이 어노테이션을 이용하면 모든 Component를 스캔하여 손쉽게 테스트를 작성할 수 있습니다만, 만약 테스트 하고 싶은 단위가 아주 작은 기능 단위라면, @SpringBootTest를 사용하는 것은 아주 비효율적입니다. 왜 비효율적인지는 @SpringBootTest의 실행 과정에서 알 수 있습니다. @SpringBootTest는 아래와 같은 순서로 실행됩니다. 테스트 클래스의 @SpringBootTest 애노테이션을 분석합니다. 이때, @SpringBootTest는 애플리케이션을 로드하기 위해 필요한 설정 정보를 포함하고 있습니다. 테스트 클래스에서 사용할 빈을 로드합니다. 이..
AOP와 @Transactional 알아보기 안녕하세요, 오늘은 자바 스프링에서 사용되는 @Transactional 어노테이션이란 무엇인지, 작동 원리에 대해서 살펴보겠습니다. Transactional에 대해 알아보기 전에, 한 번도 다룬적 없었던 AOP에 대해서도 다루어 보겠습니다. AOP?(Aspect Oriented Programming) 더보기 AOP는 인프라 로직과 비즈니스 로직을 분리해 모듈성을 높이기 위한 목적으로 사용합니다. 위 문장에서 비즈니스 로직이란 무엇일까요? 비즈니스 로직은 실세계의 규칙에 따라 데이터를 생성·표시·저장·변경하는 부분을 일컫는다라고 합니다. 즉, 데이터의 상태 값을 조작하는 로직으로 볼 수 있겠죠. DB에 데이터를 insert하거나 변경하는 로직은 모두 비즈니스 로직에 해당할 것입니다. 반대로 인프라 로직은 ..
Jar에서만 View의 경로를 찾지 못하는 이유 간단한 스프링 어플리케이션을 작성하다가 생긴 문제점에 대해 공유하고자 합니다. Static 파일이 아닌 templates 파일에 대해서 컨트롤러에서 아래 예시처럼 경로 앞에 "/"가 포함되는지 여부에 따라 jar에서는 뷰를 찾지 못하는 404 에러가 발생했습니다. @GetMapping("/users/list") public String userList(Model model) { model.addAttribute("user", joinService.lookupAllUser()); return "user/list"; // IDE + Jar에서 문제 없이 작동 } } @GetMapping("/users/list") public String userList(Model model) { model.addAttrib..