Topic = Kotlin에서 RowMapper는 어떤 객체를 사용해야 할까?
BeanPropertyRowMapper vs DataClassRowMapper
Why
RowMapper는 단순하게 쿼리 결과를 담아와서 인스턴스로 지정한 클래스에 적용시켜주는 것. 이라고 학습하고 넘어가려고 했는데 BeanPropertyRowMapper 를 사용하여 쿼리 결과를 객체로 매핑하던 중 아래와 같이 문제가 발생했다.
🚨 No argument provided for a required parameter: parameter #0 itemName
- SQL 쿼리의 결과를 클래스의 생성자에 매핑하는 과정에서 발생한 문제.
상황
- ResultSet으로 ResultSet.getString("item_name") 와 같이 수동으로 쿼리 결과를 객체에 매핑할 때는 정상적으로 불러와지다가. BeanPropertyRowMapper를 사용할 때 오류가 발생했다.
🏗️원인1. 쿼리의 결과로 생성하는 객체는 kotlin의 data class로 생성되었다.
🟥 Item - data class ( 원인코드1 )
data class Item(
var itemName : String,
...
)
🟥 RowMapper - BeanPropertyRowMapper ( 원인코드2 )
private fun rowMapper(): RowMapper<Item> {
return BeanPropertyRowMapper.newInstance(Item::class.java)
}
🌟 원인2. Java class와 Kotlin data class의 차이
java class
- 객체를 먼저 생성하고 난 뒤에 getter와 setter 메서드를 사용하여 프로퍼티에 접근하여 초기화
Kotlin data class
- 객체 생성 시 반드시 객체 프로퍼티를 통해 객체를 초기화 해야하며, 객체 생성 시 프로퍼티가 제공되지 않을 경우 예외를 발생 시킨다.
🕹️ 원인3. BeanPropertyRowMapper와 DataClassRowMapper 차이
BeanPropertyRowMapper
- 작동 방식
- 쿼리 결과를 바탕으로 먼저 객체를 생성하고, 그 후에 SQL 결과의 각 컬럼 값을 setter 메서드를 통해 객체의 프로퍼티에 설정한다.
DataClassRowMapper
- 작동 방식
- Kotlin data class에 최적화 되어 있도록 설계되었으며 SQL 쿼리의 결과를 사용할 때 객체를 생성하는 시점에서 프로퍼티 값을 전달하여 객체를 생성한다.
해결 - DataClassRowMapper를 사용하여 해결.
🟩 RowMapper - DataClassRowMapper 사용
private fun rowMapper(): RowMapper<Item> {
return DataClassRowMapper.newInstance(Item::class.java)
}
java를 사용할 경우 BeanPropertyRowMapper를, Kotlin을 사용할 경우 data class와 DataClassRowMapper를 사용하자.
만약, BeanPropertyRowMapper를 굳이 사용해야한다면?
1. dao로 dala class를 사용하지 않는다.
2. data class를 사용하지만, 속성 값을 필드로 변수 ( var ) 로 정의하고, 프로퍼티가 없는 생성자로 객체를 정의한다.
3. data class의 생성자 모든 프로퍼티 값을 Nullable로 작성하거나, Kolin no-arg( 인자가 없는 기본 생성자 자동 생성 ) 플러그인을 사용하여야한다.
[ A. 오늘 복습한 내용 / B. 다음에 학습할 내용 ]
A. java Kotlin 차이점
B. JDBC Template
B. JPA
B. no-arg 플러그인 설정하기
[Comment]
JPA를 아직 학습하진 않았지만, Java class와 Kotlin data class 차이점을 학습해보면서 kotlin spring 학습 시작하면서부터 익히 들었던 Kotlin + JPA 호환 문제가 위 문제를 덕분인걸 확 이해하게 되었다. 단순히 작동한다고 넘어가지 않아서 다행이다.
[Reference]
'웹개발 - Back 관련 > Spring-DB' 카테고리의 다른 글
[Kotlin Spring] JDBC 개념과 구성 정리해보기 (0) | 2024.08.16 |
---|---|
[Kotlin Spring] Connection, Connection Pool, DataSource 개념과 작동원리 (0) | 2024.08.14 |
[Kotlin Spring] HTTP 헤더 Content - Disposition 설정 - 문자열이 아닌 builder 패턴으로 사용하기 (0) | 2024.07.30 |