JPA 트랜잭션 커밋 전 객체에 저장된 Map이 Singleton Map으로 저장되어 LinkedHashMap으로 사용하지 못한 문제 해결

박철현·2024년 5월 16일
0

문제해결

목록 보기
14/17

문제점

  • 이전 문제 해결 이후 추가 문제 발생
  • 엔티티에 List<LinkedHashMap<String, String>>을 저장하고 커밋 전에 DTO객체로 변환하여 생성된 객체 정보를 반환하려다가 문제 발생

문제 코드

@Entity
@DynamicUpdate
class Entity {
    @Convert(converter = JsonMapConverter::class)
    @Column(columnDefinition = "json")
    var orderedMapList: List<LinkedHashMap<String, String>> = mutableListOf()

    fun initializeOrderedMapList(orderedMap : LinkedHashMap<String, String>) {
    val orderedMapKeys = orderedMap.keys.toList()
    val orderedMapValues = orderedMap.values.toList()

    this.orderedMapList = orderedMapKeys.zip(orderedMapValues).map { mapOf(it) }
}

@Transaction
fun exam01 {
	Entity entity = ...
    ...
    ..
    // 트랜잭션 종료 전(커밋 전) 객체 참조
	extractorderedMap(entity.orderedMapList)
}

fun extractOrderedMap(orderedMapList: List<LinkedHashMap<String, String>>): LinkedHashMap<String, String> {
    val result = LinkedHashMap<String, String>()
    for (orderedMap in orderedMapList) {
        val orderedMapCopy = LinkedHashMap(orderedMap)
        result.putAll(imageCopy)
    }
    return result
}
  • for문에서 바로 터져버리기~
    • class java.util.Collections$SingletonMap cannot be cast to class java.util.HashMap
  • 아니 분명히 List<LinkedHashMap<String, String>> 형태로 넣었는데 리스트 안에는 왜 도대체 SingletonMap일까!!
  • 일단 해결하는게 급하니 여러 자료를 찾다 뤼튼과 엄청난 대화 끝에.. 코드를 변경하여 해결

해결

fun extractOrderedMap(orderedMapList: List<Map<String, String>>): LinkedHashMap<String, String> {
    val result = LinkedHashMap<String, String>()
    for (orderedMap in orderedMapList) {
        val orderedMapCopy = LinkedHashMap(orderedMap)
        result.putAll(imageCopy)
    }
    return result
}

  • 매개변수를 상위타입인 List<Map<String, String>> 형태로 받아 해결
    • SingletonMap은 LinkedHashMap과 연관이 없으니 될리가있나!

도대체 왜 LinkedHashMap형태가 안된건데?!?!

  • ORM 프레임워크 내부 동작 때문
    • 트랜잭션 커밋 전 상황에 따라 실제 타입이나 내용이 예상과 다르게 동작할 수 있음
    • 커밋 전 Map을 최적화하거나 변경 사항을 추적하기 위해 단일 요소 최적화(SingletonMap 같은)를 적용할 수 있음

결론

  • 커밋 전에 해당 엔티티의 속성에서 추출하여 호출할 때 타입 에러 뜨면 상위타입으로 받도록하자!
  • 뤼튼 고맙다..!
profile
비슷한 어려움을 겪는 누군가에게 도움이 되길

0개의 댓글