현재는 VCS로 SVN을 사용하고 있는데, 다음 프로젝트에서는 git을 사용할 수도 있다고 해서 평소 사뒀던 git 관련 책을 읽었다. 개인적으로는 git을 자주 사용하고 있기 때문에 이해하기는 그렇게 어렵지 않았고, 깃의 내부 구조가 어떻게 되고 어떻게 돌아가는지 알게 되어 좋았다. 내가 참고한 책은 토미의 Git with 소스트리로, 이곳을 통해 PDF파일로 구매했다. 책은 git의 각 기능에 대해 설명하고 이를 소스트리로 어떻게 동작시키는지로 구성되어 있는데, 나의 경우 소스트리를 사용하지 않고 거의 CLI(아니면 깃크라켄)로 사용하기 때문에 소스트리 사용법은 과감하게 패스했다. 본 포스팅은 위에 말한대로 어느 정도 깃을 사용한 경험을 바탕으로 내가 모르거나 정리가 필요한 부분만 집중적으로 책의 내..

테스트를 할 때 필수적인 사항은 대량의 데이터가 준비되어 있어야 한다는 것이다. 대량의 데이터를 DB에 넣는 방법 중에 파일로 만들어서 넣는 방법이 빠르다고 해서 해보았다. 우선 CSV 파일을 만든다. 이때, 데이터는 CSV 파일에 적힌 그대로 들어가는데 VARCHAR라고 ''를 붙이게 되면 ''까지 같이 들어가게 된다. 그러니 그냥 문자열을 적는다. CSV 파일을 만들어서 서버에 옮기고 아래와 같이 실행하면 된다. load data local infile '[파일경로]' into table [insert할 테이블명] fields terminated by '[데이터 구분자. CSV의 경우 ,]' lines terminated by '\n' IGNORE 1 LINES // 첫번째 줄에는 각 컬럼명이 표시되..

JPA란 과거 자바 진행에서는 EJB 안에 엔티티 빈이라는 ORM 기술이 포함되어 있었으나, 너무 복잡하고 기술 성숙도도 떨어지고 J2EE 애플리케이션 서버에서만 동작하는 등의 어려움이 있었음. 이때 하이버네이트라는 오픈소스 ORM 프레임워크가 등장했는데 가볍고 실용적이고 기술 성숙도도 높았음. 결국 EJB 3.0에서 하이버네이트를 기반으로 새로운 자바 ORM 기술 표준이 만들어졌는데 이것이 JPA. JPA가 제공하는 CRUD API 저장 정확히 이야기하면 아래 코드는 엔티티 매니저를 사용해서 회원 엔티티를 영속성 컨텍스트에 저장한다. jpa.persist(member); 조회 String memberId = "helloId"; jpa.find(Member.class, memberId); 수정 JPA는 ..

오늘 테스트 중에 NullPointerException이 발생하는 상황이 있었고, 아래와 같이 로그를 남기고 있었다. 아래는 단순 예시. 이렇게 로그를 남기니 아래와 같은 결과가 있었다. 그런데 NullPointerException이 어디에서 발생하는지 알아야 처리를 할 수 있는데 저 정보만으로는 처리가 어려웠다. 그래서 스택트레이스를 표시해줘야했는데 아래와 같이 변경해서 표시할 수 있었다. 결과는 아래와 같다. 그래서 문득 궁금해졌다. Exception의 최상위인 Throwable은 toString()을 어떻게 정의하고 있는지, 로그에서는 e와 e.toString()을 어떻게 처리하는지. 그래서 코드를 뜯어봤다! 참고로 로그 라이브러리로 logback을 사용하고 있다. 위의 메서드를 먼저 살펴봤다. L..

Transaction이 시작되고 끝나기까지 내부 코드는 과연 어떻게 돌아가는지 궁금해서 아주 조금 뜯어보았다. 2023년 7월 25일 이하 내용 추가 본 포스팅은 @Transactional을 붙였을 때 어떻게 동작하는지 내부 코드를 뜯어본 것인데, @Transactional어노테이션을 사용할 때 프록시 기반 AOP를 사용하는데 이 AOP에 대한 내용은 빠져 있다. 트위터에 어떤 분이 AOP에 대한 내용을 풀어주셔서 살펴보고 ChatGPT가 알려준 내용을 적어둔다. 테스트에 사용한 코드는 아래와 같다. 5번 라인부터 보면 알 수 있듯이 JPA에 대해서는 JpaTransactionManager가 트랜잭션을 지원한다. 스프링에서는 트랜잭션 처리에 대해 PlatformTransactionManager 인터페이스..

개발하고 있는 내용 중에 @Transactional을 중첩해서 사용하는 경우가 있어서 이 경우에 대해 실험을 해보았다. 실험을 하면서 알게 된 사실들이 있는데, 이 사실들을 먼저 알고 보면 도움이 될 것 같아 미리 적어둔다. 1. CheckedException은 예외 발생시 롤백하지 않는다. 2. 트랜잭션 전파(propagation)의 기본 속성은 REQUIRED다. 이 속성은 미리 시작된 트랜잭션이 있으면 참여하고 없으면 새로 시작한다. 3. 동일한 클래스 내에서 @Transactional이 아닌 메서드에서 @Transactional 메서드를 호출하면 트랜잭션이 적용되지 않는다. 3. 트랜잭션 전파의 속성 중 REQUIRES_NEW는 동일한 클래스의 메서드들끼리 호출하면 작동하지 않고, 반드시 다른 클..
업무에서 파라미터 유효성 체크를 할 때 각 클래스마다 checkParam의 방식으로 유효성 체크를 해왔는데, 좀 더 편하게 할 수 있는 방법이 없을까 고민했고, 이 글은 고민했던 내용을 적은 것이다. 우선은 기존에도 가지고 있었지만 사용하지는 않았던 Validation을 사용해보기로 했다. 기본적인 흐름은 다음과 같다. 1. 컨트롤러의 메서드 호출 2. @Valid 어노테이션이 붙은 파라미터의 유효성 조건 체크 3. 유효성 조건을 만족하지 못하면 ControllerAdvisor의 해당 Exception의 ExceptionHandler 어노테이션이 붙은 메서드가 수행된다. @Controller @RequestMapping("/post") public class TestPostController { @Res..
자바에서 throw를 통해 발생시킬 수 있는 예외는 크게 세 가지가 있다. Error Exception과 CheckedException java.lang.Exception 클래스와 그 서브클래스 + Exception 클래스의 서브클래스이면서 RuntimeException 클래스를 상속하지 않은 클래스 컴파일시 예외처리가 되어있는지 확인 -> Checked RuntimeException과 UncheckedException java.lang.Exception 클래스의 서브클래스이면서 RuntimeException을 상속한 클래스