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년이 지났는데, 관련 오류가 그다지 많이 올라오진 않았네요.
급하게 과제 수행하고자 인터넷을 뒤졌는데, 답이 안나와서 결국 디버그 모드로 해결했는데,

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

Nov 12, 2020 - Unite Seoul 2020

Unite Seoul 2020 입니다.
모두들 참가신청합시다!!!

세미나를 좋아하고, Unity 2D에 대해 조금 관심있어,

유투브를 찾다가,

event0

okky 에서 광고성 DM을 받아, 별 생각없이 세미나를 등록했습니다.

event1

우와 1등 상품이 무려!!!!! 플레이스테이션5 !!!!! 뭐 쓸일은 없지만요.

룰렛을 돌려봅시다.

어? 돌리기전에 이상하네요..

어? 돌리기도 전에 왜 당첨팝업과, 꽝팝업이 있는걸까요…

event2

우리에겐 display none; 을 해결해줄, 크롬 개발자도구가 있잖아요 !!!

event3

두둥!! 당첨자에게는 비타 500 !!!!

으응?

그냥 하드코딩으로 박혀있는데요? 5등이? 합격되든 안되든?

event4

“에이, 설마아아~ 당첨되면 화면을 덮어씌우겠지~~~~”

하기에는 너무나 정직한 소스였습니다.

event5

…………..

즐거운 Unite Seoul 2020을 서둘러 등록해야 하는 이유! 지금 등록하면 룰렛을 5번이나 돌릴 수 있습니다!!!
당첨되면 비타 500을요!!!! 1~4위까지는 누가 가져가는걸까요. ^-^;

추가사항. .html(data.code) 로 html 을 덮어 씌워서 당첨시 플레이스테이션의 정보로 덮어씌울 수도 있습니다.
계속 당첨이 안되니, 해당값을 확인못하니까, 그냥 지레짐작했을 확률이 크네요.. …