DevLog ๐Ÿ˜ถ

[Spring] Kotlin์—์„œ data class์˜ ํ•„๋“œ๊ฐ€ 1๊ฐœ์ผ ๋•Œ ์—ญ์ง๋ ฌํ™”๊ฐ€ ์•ˆ ๋˜๋Š” ๋ฌธ์ œ (no delegate- or property-based Creator) ๋ณธ๋ฌธ

๊ฐœ๋ฐœ์ผ์ง€

[Spring] Kotlin์—์„œ data class์˜ ํ•„๋“œ๊ฐ€ 1๊ฐœ์ผ ๋•Œ ์—ญ์ง๋ ฌํ™”๊ฐ€ ์•ˆ ๋˜๋Š” ๋ฌธ์ œ (no delegate- or property-based Creator)

dolmeng2 2023. 6. 23. 15:03

๐ŸŒฑ ๋ฌธ์ œ ์ƒํ™ฉ

๊ฐ„๋‹จํ•˜๊ฒŒ ํ…Œ์ŠคํŠธํ•˜๊ณ  ์‹ถ์€ ๋‚ด์šฉ์ด ์ƒ๊ฒจ์„œ DTO์šฉ data class๋ฅผ ์ƒ์„ฑํ•˜์˜€๋Š”๋ฐ, ์•„๋ž˜์™€ ๊ฐ™์ด Jackson์˜ ์—ญ์ง๋ ฌํ™” ๊ด€๋ จ ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ•˜์˜€๋‹ค.

Resolved [org.springframework.http.converter.HttpMessageNotReadableException: JSON parse error: Cannot construct instance of `study.ticketService.domain.application.dto.ConcertTicketCreateRequest` (although at least one Creator exists): cannot deserialize from Object value (no delegate- or property-based Creator)]

๋Œ€์ถฉ ์˜ค๋ฅ˜๋ฅผ ๋ณด๋ฉด ์—ญ์ง๋ ฌํ™”๋ฅผ ํ•ด์•ผ ํ•˜๋Š”๋ฐ ๊ธฐ๋ณธ ์ƒ์„ฑ์ž๊ฐ€ ์—†์–ด์„œ ํ•  ์ˆ˜ ์—†๋‹ค๋Š” ๋‚ด์šฉ์ด๋‹ค.

 

data class ConcertTicketCreateRequest(
    @NotNull(message = "์‚ฌ์šฉ์ž ์•„์ด๋””๋Š” ๋น„์–ด์žˆ์„ ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.")
    val userId: Long
)

 

๋ฌธ์ œ๊ฐ€ ๋œ data class๋Š” ์œ„์™€ ๊ฐ™๋‹ค. 

 

 

Jackson fails to deserialize 1 field POJO · Issue #3085 · FasterXML/jackson-databind

Describe the bug When trying to deserialize JSON to POJO it fails when POJO has only one field. Version information 2.11.4 To Reproduce POJO: @AllArgsConstructor //lombok, if i add constructor manu...

github.com

์ด ๊นƒํ—ˆ๋ธŒ ์ด์Šˆ์— ๊ฐ€๋ฉด ์นœ์ ˆํ•˜๊ฒŒ ๊ทธ ์ด์œ ๋ฅผ ์„ค๋ช…ํ•ด์ค€๋‹ค.

ํ•„๋“œ๊ฐ€ 1๊ฐœ์ธ ๊ฒฝ์šฐ ๊ธฐ๋ณธ ์ƒ์„ฑ์ž๋ฅผ ๋งŒ๋“œ๋Š” ์ „๋žต์ด Delegating / Properties-based๋กœ ๋‚˜๋‰˜๋Š”๋ฐ, ๋‘ ๋ชจ๋“œ ์ค‘์—์„œ ์–ด๋–ค ๊ฒƒ์„ ์„ ํƒํ•ด์•ผ ํ• ์ง€ ์•Œ ์ˆ˜ ์—†์–ด์„œ ๋ฐœ์ƒํ•œ ์˜ค๋ฅ˜์ธ ๊ฒƒ์ด๋‹ค.

์œ„ ์ด์Šˆ์—์„œ๋Š” @JsonCreator ์–ด๋…ธํ…Œ์ด์…˜์„ ํ†ตํ•ด์„œ ๋ช…์‹œ์ ์œผ๋กœ ๋ชจ๋“œ๋ฅผ ์ง€์ •ํ•ด์ฃผ๋Š” ๋ฐฉ๋ฒ•์„ ์†Œ๊ฐœํ•˜๋Š”๋ฐ, data class์—์„œ ์–ด๋–ป๊ฒŒ ๊ธฐ๋ณธ ์ƒ์„ฑ์ž๋ฅผ ๋งŒ๋“ค ์ˆ˜ ์žˆ์„๊นŒ?

 


 

๐ŸŒฑ ํ•ด๊ฒฐ ๋ฐฉ๋ฒ•

๊ฒฐ๋ก ๋ถ€ํ„ฐ ๋งํ•˜์ž๋ฉด, ๊ธฐ๋ณธ๊ฐ’์„ ๋ช…์‹œ์ ์œผ๋กœ ์ง€์ •ํ•˜๊ฑฐ๋‚˜, ๋ถ€์ƒ์„ฑ์ž๋ฅผ ํ™œ์šฉํ•˜๊ฑฐ๋‚˜, @JsonProperty๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ๋œ๋‹ค.

 

๐Ÿ’ฌ ๊ธฐ๋ณธ ๊ฐ’ ์ง€์ •ํ•˜๊ธฐ

data class ConcertTicketCreateRequest(
    @NotNull(message = "์‚ฌ์šฉ์ž ์•„์ด๋””๋Š” ๋น„์–ด์žˆ์„ ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.")
    val userId: Long = 0L
)

์ฃผ์ƒ์„ฑ์ž ์ž์ฒด์— ๊ธฐ๋ณธ ๊ฐ’์„ ์ง€์ •ํ•ด์ค€๋‹ค. id ๊ฐ’์€ ํ•ญ์ƒ ๋นˆ ๊ฐ’์ด ๋“ค์–ด์˜ค์ง€ ์•Š๊ธฐ ๋•Œ๋ฌธ์— ์–ด์ฐจํ”ผ ๋Œ€์ฒด๋  ๊ฐ’์ด๋ผ์„œ ์ƒ๊ด€์—†๋‹ค.

 

 

๐Ÿ’ฌ ๋ถ€์ƒ์„ฑ์ž ์‚ฌ์šฉํ•˜๊ธฐ

data class ConcertTicketCreateRequest(
    @NotNull(message = "์‚ฌ์šฉ์ž ์•„์ด๋””๋Š” ๋น„์–ด์žˆ์„ ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.")
    val userId: Long
) {
    constructor() : this(0)
}

ํ˜น์€, ๋ถ€์ƒ์„ฑ์ž๋ฅผ ํ™œ์šฉํ•ด์„œ ๋‚ด๋ถ€์ ์œผ๋กœ ๊ธฐ๋ณธ๊ฐ’์„ ์ดˆ๊ธฐํ™”ํ•ด์ค€ ์ƒ์„ฑ์ž๋ฅผ ๋งŒ๋“ค์–ด์ค„ ์ˆ˜ ์žˆ๋‹ค.

 

 

๐Ÿ’ฌ @JsonProperty ํ™œ์šฉํ•˜๊ธฐ

data class ConcertTicketCreateRequest(
    @JsonProperty("userId")
    @NotNull(message = "์‚ฌ์šฉ์ž ์•„์ด๋””๋Š” ๋น„์–ด์žˆ์„ ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.")
    val userId: Long
)

ํ•˜์ง€๋งŒ, ๊ธฐ๋ณธ๊ฐ’์„ ์ง€์ •ํ•˜๊ฑฐ๋‚˜ ๊ธฐ๋ณธ ์ƒ์„ฑ์ž๋ฅผ ๋งŒ๋“ค์–ด๋‘”๋‹ค๋Š” ๊ฒŒ ์ƒ๋‹นํžˆ ์ฐ์ฐํ•œ ์ผ์ฒ˜๋Ÿผ ๋Š๊ปด์งˆ ์ˆ˜ ์žˆ๋‹ค.

์ด๋•Œ๋Š” @JsonProperty๋ฅผ ํ†ตํ•ด์„œ ๋ช…์‹œ์ ์œผ๋กœ json ๊ฐ’์˜ key์™€ ํ•ด๋‹น ๊ฐ์ฒด์˜ ํ•„๋“œ๋ฅผ ๋งค์นญ์‹œ์ผœ์ค„ ์ˆ˜ ์žˆ๋‹ค.

ํ•ด๋‹น ์–ด๋…ธํ…Œ์ด์…˜์— ๋Œ€ํ•ด์„œ ์ข€ ๋” ์•Œ๊ณ  ์‹ถ๋‹ค๋ฉด ์ด ๊ธ€์„ ์ฐธ๊ณ ํ•ด ์ฃผ์„ธ์š”! ๐Ÿ˜Ž

 

 

๊ฐœ์ธ์ ์œผ๋กœ๋Š” 1๋ฒˆ ๋ฐฉ๋ฒ•์ด ๊ฐ€์žฅ ๊น”๋”ํ•ด์„œ ๊ทธ๋ƒฅ ๊ธฐ๋ณธ๊ฐ’์„ ์ง€์ •ํ•ด์ฃผ๋Š” ๊ฑธ๋กœ ๋งŒ๋“ค์—ˆ๋‹ค.

์˜ค๋ฅ˜ ์—†์ด ์ž˜ ๋“ค์–ด๊ฐ€๋Š” ๊ฒƒ์„ ๋ณผ ์ˆ˜ ์žˆ๋‹ค.

Comments