Nov 18, 2020 - EditorConfig

이번 과제를 3개 정도 동시에 수행하면서,
회사 프로젝트의 코드컨밴션과 과제 한곳과 다른 부분 때문에 고생했습니다.

그런데, .editorconfig 라는 파일이 존재하는 것을 알게되어,
히스토리를 남깁니다.

Spring-boot editorconfig

root=true

[*.{groovy,java,kt,xml}]
indent_style = space
indent_size = 4
continuation_indent_size = 4

저는 “Tab vs Space, 2글자 vs 4글자” 에서, 현재 저는 2 Space 신봉자입니다.
(확실히 안이쁘긴 합니다.)

예전엔 8자리 띄워쓰기를 하는 경우도 있었지만,
지금은 보통 4자리 띄어쓰기가 기본으로 알고 있습니다.

2 space 를 선호하게 된 것은 인텔리J를 쓰게 되면서 줄당 평균 글자수를 지키고 싶었기 때문입니다.

물론, 4글자를 써서, 줄당 평균 글자수를 강제로 줄여주는 효과에 대해서도 고민해보았지만,
현업이란게, 저만 글자수를 줄인다고 해결되는 것이 아니니까요.

만약 모든 분들이 글자수를 강제로 줄이는 부분에 대해서 같이 고민하는 회사라면,
과감히 Tab 과 4 글자도 도전해보고 싶네요! 저도 많은 경험을 하게 되겠지요!

여하튼,

# top-most EditorConfig file
root = true

[*]
# [encoding-utf8]
charset = utf-8

# [newline-lf]
end_of_line = lf

# [newline-eof]
insert_final_newline = true

[*.bat]
end_of_line = crlf

[*.java]
# [indentation-tab]
indent_style = tab

# [4-spaces-tab]
indent_size = 4
tab_width = 4

# [no-trailing-spaces]
trim_trailing_whitespace = true

[line-length-120]
max_line_length = 120

과제중, Tab 과 4글자로 강제하는 과제가 있었습니다.
기존 프로젝트에 영향을 주는 과제였고,
또 다른 과제는 인텔리J의 기본 컨벤션을 사용하라는 과제였습니다.

그리고 회사에서는 2글자와 2space를 사용하고 있고요!!!

결국, .editorconfig 를 이용해서, 잘 해결했다고 생각합니다.
무언가 도전(?)한다는 것은 무언가를 얻을 확률이 높다는 걸 다시한번 경험합니다!

Nov 17, 2020 - ApplicationContext.getBean()

과제 수행하다가 갑자기 생각났던 내용을 정리합니다.

Spring IoC 컨테이너가 관리하는 자바 객체를 우리는 빈(Bean)이라고 부릅니다.

new 객체를 Bean 객체라고 부르지 않습니다.

회사 레거시 소스 중 서블릿 Api 가 있고, 그곳에 스프링기능을 쓸 때는, ApplicationContext.getBean()을 사용해와서, 별 생각없이 사용해왔습니다. (applicationContext.xml 에 해당 bean 객체를 생성하여(init 포함), 관리를 하고 있습니다.)

Spring에서의 빈은 ApplicationContext가 알고있는 객체로,
ApplicationContext가 만들어서 그 안에 담고있는 객체를 의미합니다.

스프링부트에서 Exception 발생 시, 내부적으로 빈객체를 호출해서 사용해야하는 경우가 생겨, 관련된 내용을 정리해둡니다.

  1. Bean을 가져오기 위해서는 ApplicationContext 를 생성
   import org.springframework.beans.BeansException;
   import org.springframework.context.ApplicationContext;
   import org.springframework.context.ApplicationContextAware;
   import org.springframework.stereotype.Component;
    
   @Component
   public class ApplicationContextProvider implements ApplicationContextAware {
    
       private static ApplicationContext applicationContext;
    
       @Override
       public void setApplicationContext(ApplicationContext ctx) throws BeansException {
           applicationContext = ctx;
       }
    
       public static ApplicationContext getApplicationContext() {
           return applicationContext;
       }
    
   }
  1. 그 다음 ApplicationContext를 사용하는 BeanUtils를 생성
public class BeanUtils {
 
    public static Object getBean(String beanName) {
        ApplicationContext applicationContext = ApplicationContextProvider.getApplicationContext();
        return applicationContext.getBean(beanName);
    }
 
}
  1. BeanUtils을 통해 @Autowired 없이 빈객체 호출
        A a = (A) BeanUtils.getBean("xxxxx");

Nov 15, 2020 - Data conversion error converting

과제 수행 중, 알 수 없는 오류가 발생했습니다.

; Data conversion error converting "black" [22018-200]; nested exception is org.h2.jdbc.JdbcSQLDataException: Data conversion error converting "black" [22018-200]] with root cause

java.lang.NumberFormatException: For input string: "black"
	at java.base/java.lang.NumberFormatException.forInputString(NumberFormatException.java:68) ~[na:na]
	at java.base/java.lang.Integer.parseInt(Integer.java:652) ~[na:na]
	at java.base/java.lang.Integer.parseInt(Integer.java:770) ~[na:na]
	at org.h2.value.Value.convertToInt(Value.java:982) ~[h2-1.4.200.jar:1.4.200]
	at org.h2.value.Value.convertTo(Value.java:806) ~[h2-1.4.200.jar:1.4.200]
	at org.h2.value.Value.convertTo(Value.java:737) ~[h2-1.4.200.jar:1.4.200]
	at org.h2.value.Value.getInt(Value.java:623) ~[h2-1.4.200.jar:1.4.200]
	at org.h2.jdbc.JdbcResultSet.getInt(JdbcResultSet.java:352) ~[h2-1.4.200.jar:1.4.200]

알 수 없는 에러 발생, color 라는 컬럼은 생성시 varchar로 생성하였는데 int 형 변수로 convert 하다가 실패하는 오류였습니다.
h2 의 버전 문제인가 했는데 그것도 아니고,
어떻게 보면 단순한 NumberFormatException 이슈였습니다.

데이터를 넣을 때,
color 를 ‘black’에서 number형인 ‘2’로 변경 시, 정상 동작되는 것을 보면,
insert 이슈도 아니고 실제 데이터베이스에서는 정상적으로 ‘black’이라는 단어가 들어있는 것을 확인했습니다.

혹시 순서나 변수선언에서 잘못된 것이 있을지도 몰라,
color 를 productColor 로 변경 시 여전히, 에러 발생.

정확한 원인 발생 전 전체 로직 테스트를 위해 ‘2’로 변경 후 테스트 진행을 하였습니다.

원인은 바로 @Builder의 문제였습니다.

image

테스트가 끝나고, 원인 분석에 들어갔습니다.
에러난 위치에서 디버그 모드로 확인해보니, 해당 컬럼을 int로 치환하다가 발생하는 문제….!?!

import lombok.Builder;
import lombok.Data;
import lombok.ToString;

@Data
@Builder
@ToString
public class UserConversion {
    private int userId;
    private int productId;
    private int couponId;
    private int point;
    private int productCount;
    private int productPrice;
    private String productColor;
    private String size;
    private int discountAmount;
}

lombok 에서 제공하는 @Builder 와 Mabatis 의 resultType과의 변수들끼리 매핑해야하는 순서 문제로,
동일하게 맞추어 문제를 해결했습니다.

Mapper에서 builder로 자동 맵핑하는 게 적용된 지 벌써 2년이 지났는데, 관련 오류가 그다지 많이 올라오진 않았네요.
급하게 과제 수행하고자 인터넷을 뒤졌는데, 답이 안나와서 결국 디버그 모드로 해결했는데,

정답은 인터넷에 있는게 아니라 소스에 있다고 다시한번 깨닫는 하루였습니다.