오늘은 개인프로젝트에 @ControllerAdvice를 추가해서 유효하지 않은 파라미터를 공통으로 처리해주는 작업을 하고 있었다. 테스트코드 작성해서 테스트하는데 분명 제대로 작성했는데 @ControllerAdvice가 적용되지 않는 것이었다. @ControllerAdvice가 다른 패키지에 있었는데, 혹시나 해서 컨트롤러 안에 @ExceptionHandler 메서드만 넣으니까 잘 작동하고. 위 이미지를 비교해보면 알 수 있듯이 제대로 작동하지 않은 경우에는 DefaultHandlerExceptionResolver로 BindException이 처리됐고, 제대로 작동한 경우에는 ExceptionHandlerExceptionResolver로 처리가 됐다. DefaultHandlerExceptionResolv..
개인프로젝트를 헤로쿠에 배포해놓고 있었는데, 갑자기 저런 메일이 왔다. 세번째 줄 보면 your database credentials and hostname will have changed, but we will update your app's config variables accordingly to reflect the new database connection string. 이라고 되어 있다. 내 개인프로젝트는 헤로쿠에서 제공하는 postgresql을 사용하고 있다. 이 DB에 접근하기 위한 정보가 credentials이고. 그런데 보안때문에 credentials 변경이 발생한다는 것이다. 문제는 종료되었다는 메일이 왔는데도 내 credentials는 변경되지 않았다. 헤로쿠에 올라가있는 서버를 다시..
오늘 테스트 중에 NullPointerException이 발생하는 상황이 있었고, 아래와 같이 로그를 남기고 있었다. 아래는 단순 예시. 이렇게 로그를 남기니 아래와 같은 결과가 있었다. 그런데 NullPointerException이 어디에서 발생하는지 알아야 처리를 할 수 있는데 저 정보만으로는 처리가 어려웠다. 그래서 스택트레이스를 표시해줘야했는데 아래와 같이 변경해서 표시할 수 있었다. 결과는 아래와 같다. 그래서 문득 궁금해졌다. Exception의 최상위인 Throwable은 toString()을 어떻게 정의하고 있는지, 로그에서는 e와 e.toString()을 어떻게 처리하는지. 그래서 코드를 뜯어봤다! 참고로 로그 라이브러리로 logback을 사용하고 있다. 위의 메서드를 먼저 살펴봤다. L..
NOR게이트 두 개가 연결되어 있다고 하자. 한 NOR게이트의 출력은 다른 NOR게이트의 입력으로 들어가고, 다시 그 게이트의 출력은 첫번째 NOR게이트의 입력으로 들어간다. 간단히 나타내기 위해 1번 게이트, 2번 게이트라고 하자. 1번 게이트와 2번 게이트에는 입력으로 연결된 스위치가 있다. 1번 게이트에 연결된 스위치를 닫게 되면 게이트의 입력으로 1이 들어가게 되어 2번 게이트의 입력으로 출력인 1이 들어가게 된다. 그러면 2번 게이트는 1이라는 출력을 갖게 되고(NOR게이트이기 때문) 그 출력은 다시 1번 게이트의 입력으로 들어가게 되어 결과적으로 출력이 연결된 전구에 불이 들어오게 된다. 이때, 1번 게이트에 연결된 스위치를 떼더라도 1이라는 입출력이 회로에서 반복되기 때문에 불은 계속 켜져 ..
큐(Queue)라는 자료구조는 선입선출(FIFO)이다. 데이터가 들어가는 위치(rear)와 나오는 위치(front)에 대한 포인터가 있다. 하지만 나중에 들어온 데이터라도 우선순위가 높다면 먼저 처리해주는게 효율적이다. 이런 자료구조를 우선순위 큐라고 한다. 큐의 경우, front에 위치해있는 데이터를 내보내고, rear에 데이터를 삽입하지만, 우선순위 큐는 구조가 다르다. front는 모든 데이터들 중 우선순위가 가장 높은 데이터가 위치해서 우선순위에 따라 처리할 수 있도록 하고, 우선순위에 따라 처리되면 그 다음으로 우선순위가 높았던 데이터가 front로 위치하고 빈 공백을 메우기 위해 모든 데이터들이 이동한다. rear에 데이터를 삽입할 때는 front에 위치해있는 데이터와 우선순위를 비교해서 fr..
Transaction이 시작되고 끝나기까지 내부 코드는 과연 어떻게 돌아가는지 궁금해서 아주 조금 뜯어보았다. 2023년 7월 25일 이하 내용 추가 본 포스팅은 @Transactional을 붙였을 때 어떻게 동작하는지 내부 코드를 뜯어본 것인데, @Transactional어노테이션을 사용할 때 프록시 기반 AOP를 사용하는데 이 AOP에 대한 내용은 빠져 있다. 트위터에 어떤 분이 AOP에 대한 내용을 풀어주셔서 살펴보고 ChatGPT가 알려준 내용을 적어둔다. 테스트에 사용한 코드는 아래와 같다. 5번 라인부터 보면 알 수 있듯이 JPA에 대해서는 JpaTransactionManager가 트랜잭션을 지원한다. 스프링에서는 트랜잭션 처리에 대해 PlatformTransactionManager 인터페이스..
이 고민은 파라미터 유효성 체크를 편하게 하는 방법을 찾아보다가 시작되었다.(파라미터 유효성 체크를 편하게 해보자) 현재 우리 프로젝트는 JSP뷰를 사용하고 있다. 그리고 한 컨트롤러 클래스에는 뷰를 호출하는 메서드와 @ResponseBody를 사용하여 데이터를 내려주는 Ajax용 메서드가 혼재해있다. 그말인즉 컨트롤러에서 예외가 발생하면 잡아서 처리해줄 ControllerAdvice에서는 같은 예외에 따라 뷰를 내려줘야할수도, 데이터를 내려줘야할 수도 있다는 것이다. @ControllerAdvice 여러 개로 해결하는 방법 그래서 @ControllerAdvice의 적용범위를 제한하는 방법을 생각했다. 특정 어노테이션을 가지고 있는지, 특정 패키지 이하에 존재하는지, 특정 클래스 타입인지 등을 확인하여 ..
개발하고 있는 내용 중에 @Transactional을 중첩해서 사용하는 경우가 있어서 이 경우에 대해 실험을 해보았다. 실험을 하면서 알게 된 사실들이 있는데, 이 사실들을 먼저 알고 보면 도움이 될 것 같아 미리 적어둔다. 1. CheckedException은 예외 발생시 롤백하지 않는다. 2. 트랜잭션 전파(propagation)의 기본 속성은 REQUIRED다. 이 속성은 미리 시작된 트랜잭션이 있으면 참여하고 없으면 새로 시작한다. 3. 동일한 클래스 내에서 @Transactional이 아닌 메서드에서 @Transactional 메서드를 호출하면 트랜잭션이 적용되지 않는다. 3. 트랜잭션 전파의 속성 중 REQUIRES_NEW는 동일한 클래스의 메서드들끼리 호출하면 작동하지 않고, 반드시 다른 클..