Mybatis 기본 생성자가 없는 경우
Mybatis에서는 기본 생성자가 없는 경우 Mapper에 정의된 규칙을 사용하지 않는다. 주 생성자의 파라미터와 조회해 온 데이터를 순서대로 매핑을 한다. DefaultResultSetHandler 클래스에서 createResultObject를 통해서 확인을 할 수 있다.
hasDefaultConstructor 메서드는 파라미터 개수가 0인 생성자 여부를 알려주며, 이것이 충족하지 않을 때 Mybatis에서 정한 규칙에 따라 자동으로 객체와 데이터를 매핑을 해준다.
✅ DefaultResultSetHandler.java
private Object createResultObject(...){
if (hasTypeHandlerForResultObject(rsw, resultType)) {}
else if (resultType.isInterface() || metaType.hasDefaultConstructor()) {
return objectFactory.create(resultType);
} else if (shouldApplyAutomaticMappings(resultMap, false)) {
return createByConstructorSignature(rsw, resultType, constructorArgTypes, constructorArgs);
}
}
Data Class를 사용할 때 주의점
코틀린의 Data Class의 경우 별도로 생성자를 정의하지 않으면, 전체 멤버 변수를 담고 있는 주 생성자를 하나 생성한다. 이렇게 되면 기본 생성자를 만들어지지 않는다. 이는 조회해 온 데이터의 컬럼 순서대로 매핑이 된다는 것을 의미한다. 이것을 간과하고 사용을 한다면, 매핑 과정에서 데이터 타입이 안 맞는 등의 예외가 발생할 수 있다.
✅ 예외를 방어하며 사용하기
1. Data Class의 변수에 기본 값을 설정을 해주는 방법이 있다. 이렇게 하면 기본 생성자가 만들어지기 때문이다.
data class User(val name: String = "홍길동", val age: Int = 0)
2. MyBatis 3.4.3+ 부터 @ConstructorProperties 어노테이션을 사용하면 기본 값 없이도 원하는 규칙에 따라 생성을 할 수 있다.
import java.beans.ConstructorProperties
data class User @ConstructorProperties("name", "age") constructor(
val name: String,
val age: Int
)
배우고 좋았던 점
회사에서 최근 코틀린 코드를 작성할 일이 많아지면서 기존에 사용하고 있던 Mybatis를 쓸 때 위와 같은 것을 간과해서 문제가 발생했다. 처음에는 그냥 문제만 해결하고 가려고 했는데, 하는 김에 원인 파악을 같이 하면 이후에 도움이 될 것 같았다. 시간은 더 걸렸지만 이를 통해 부족했던 코틀린 Data Class의 지식도 같이 얻을 수 있어서 좋았다.
'프로젝트' 카테고리의 다른 글
Redis Scan으로 Key 삭제하기 (0) | 2024.12.07 |
---|---|
시간 유효성 검사에서 시간 값 생성 시점 (0) | 2024.11.03 |
불변 객체와 깊은 복사를 사용 해야 하는 이유 (0) | 2024.10.28 |
Github PR을 했을 때 Slack 알림 보내기 (0) | 2024.10.21 |
재화(크레딧, 투표권 등) 로그 데이터 정리 작업 (0) | 2024.09.02 |