๋ณธ๋ฌธ ๋ฐ”๋กœ๊ฐ€๊ธฐ

BackEnd๐ŸŒฑ/Spring47

AbstractAggregateRoot์™€ ApplicationEventPublisher ๋™์ž‘ ๊ณผ์ • ๊ฐœ์š”์Šคํ”„๋ง์˜ ์ด๋ฒคํŠธ ๊ธฐ๋Šฅ์„ ํ™œ์šฉํ•  ๋•Œ ํ”ํžˆ AbstractAggregateRoot ํ˜น์€ ApplicationEventPublisher๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค. ์ด ๊ธ€์—์„œ๋Š” ๋‚ด๋ถ€์ ์œผ๋กœ ์–ด๋–ค ๋ฐฉ์‹์œผ๋กœ ๋™์ž‘ํ•˜๋ฉฐ, ์ด๋ฒคํŠธ๊ฐ€ ์–ด๋–ป๊ฒŒ ๋“ฑ๋ก๋˜๊ณ  ๋ฐœํ–‰๋˜์–ด ์ตœ์ข…์ ์œผ๋กœ ์ˆ˜์‹ ๋˜๋Š”์ง€ ์ „์ฒด์ ์ธ ๊ณผ์ •์„ ์ •๋ฆฌํ•ด ๋ณธ๋‹ค. AbstractAggregateRoot ๋™์ž‘ ๊ณผ์ •AbstractAggregateRoot๋Š” Spring Data์—์„œ ์ œ๊ณตํ•˜๋Š” ์ถ”์ƒ ํด๋ž˜์Šค๋กœ, ๋„๋ฉ”์ธ ์ด๋ฒคํŠธ๋ฅผ ๋ณด๋‹ค ์†์‰ฝ๊ฒŒ ๋“ฑ๋กํ•˜๊ณ  ๊ด€๋ฆฌํ•  ์ˆ˜ ์žˆ๋„๋ก ๋„์™€์ค€๋‹ค. ์ฃผ๋กœ DDD์—์„œ ์ƒํƒœ ๋ณ€๊ฒฝ ํ›„ ์™ธ๋ถ€์— ์˜๋ฏธ ์žˆ๋Š” ์ด๋ฒคํŠธ๋ฅผ ์ „๋‹ฌํ•  ๋•Œ ์‚ฌ์šฉ๋œ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด ์ฃผ๋ฌธ์ด ์™„๋ฃŒ๋˜์—ˆ์„ ๋•Œ ๋„๋ฉ”์ธ ์ด๋ฒคํŠธ๋ฅผ ๋“ฑ๋กํ•˜๋Š” ์ฝ”๋“œ๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™๋‹ค.@Entitypublic class Order extends Abstr.. 2025. 6. 28.
๋‚˜๋Š” GET์œผ๋กœ ๋ณด๋ƒˆ๋Š”๋ฐ ์™œ POST๋กœ ๊ฐˆ๊นŒ? (feat. OpenFeign ๊ธฐ์—ฌ) ๊ฐœ์š”์ตœ๊ทผ OpenFeign์„ ์‚ฌ์šฉํ•  ๋•Œ ์ด์ƒํ•œ ๋ฌธ์ œ๋ฅผ ๊ฒช์—ˆ๋‹ค. @FeignClient(name = "test-client")public interface TestClient { @GetMapping("/test") String getData(String query);}์œ„์™€ ๊ฐ™์ด ์ •์˜๋œ OpenFeignํด๋ผ์ด์–ธํŠธ๋ฅผ ํ†ตํ•ด A ์„œ๋ฒ„์—์„œ B ์„œ๋ฒ„์˜ API๋ฅผ ํ˜ธ์ถœํ–ˆ๋Š”๋ฐ, 405 Method Not Allowed ์—๋Ÿฌ๊ฐ€ ๋ฐœ์ƒํ–ˆ๋‹ค. ๋ถ„๋ช… B ์„œ๋ฒ„์—๋Š” ํ•ด๋‹น API๊ฐ€ GET ๋ฉ”์„œ๋“œ๋กœ ์ •ํ™•ํžˆ ์ •์˜๋˜์–ด ์žˆ๋Š”๋ฐ๋„ ๋ง์ด๋‹ค.@Slf4jpublic class FeignLoggingInterceptorConfig { @Bean public RequestInterceptor requestLoggingInterce.. 2025. 5. 26.
Hibernate 5.x → 6.x QueryDSL ๊ด€๋ จ ์ด์Šˆ ๊ฐœ์š”Spring Boot 2.7.x์—์„œ Spring Boot 3.3.x๋กœ ๋ฒ„์ „ ์—…๊ทธ๋ ˆ์ด๋“œ๋ฅผ ์ง„ํ–‰ํ•˜๋ฉด์„œ ๋ฐœ์ƒํ•œ ์—ฌ๋Ÿฌ ๋ฌธ์ œ ์ค‘์—์„œ QueryDSL๊ณผ ๊ด€๋ จ๋œ ์ด์Šˆ๋ฅผ ๊ณต์œ ํ•˜๊ณ ์ž ํ•œ๋‹ค. (Hibernate ๋ฒ„์ „์—… ์ง„ํ–‰ํ•  ๋•Œ Migration Guides๋ฅผ ์ฐธ๊ณ ํ•˜๋ฉด ๋„์›€ ๋œ๋‹ค.)๋จผ์ € Spring Boot๊ฐ€ 3.x ๋ฒ„์ „๋Œ€๋กœ ์˜ฌ๋ผ์˜ค๋ฉด์„œ Hibernate๋„ ๊ธฐ๋ณธ์ ์œผ๋กœ 6.1 ๋ฒ„์ „์ด ์ ์šฉ๋œ๋‹ค. ์ด์— ๋งž์ถฐ Hibernate๋ฅผ v6.5.3.Final๋กœ ์—…๊ทธ๋ ˆ์ด๋“œํ–ˆ์œผ๋‚˜ ์˜ํ–ฅ์œผ๋กœ ์ด์ „๊นŒ์ง€ ๋ฌธ์ œ์—†์ด ๋™์ž‘ํ•˜๋˜ ์ผ๋ถ€ QueryDSL ๋กœ์ง์—์„œ ์—๋Ÿฌ๊ฐ€ ๋ฐœ์ƒํ•˜๊ธฐ ์‹œ์ž‘ํ–ˆ๋‹ค. 1. InvalidDataAccessApiUsageException: org.hibernate.query.sqm.AliasCollisionExceptionprivate .. 2025. 3. 28.
Spring ํŠธ๋žœ์žญ์…˜์€ ์–ธ์ œ ์–ด๋–ป๊ฒŒ ๋กค๋ฐฑ ๋ ๊นŒ? -2ํŽธ(feat. rollback-only) ๊ฐœ์š”์ด์ „ ๊ธ€์—์„œ๋Š” Spring์˜ @Transactional ์–ด๋…ธํ…Œ์ด์…˜์ด ๊ธฐ๋ณธ์ ์œผ๋กœ ์–ด๋–ป๊ฒŒ ๋™์ž‘ํ•˜๋Š”์ง€, ๊ทธ๋ฆฌ๊ณ  ์˜ˆ์™ธ ์ฒ˜๋ฆฌ์— ๋”ฐ๋ผ ํŠธ๋žœ์žญ์…˜์ด ๋กค๋ฐฑ๋˜๋Š” ๋ฉ”์ปค๋‹ˆ์ฆ˜์— ๋Œ€ํ•ด ๋‹ค๋ฃจ์—ˆ๋‹ค. ์ด๋ฒˆ ๊ธ€์—์„œ๋Š” ์‹ค์ œ ์ฝ”๋“œ์™€ ํ…Œ์ŠคํŠธ๋ฅผ ํ†ตํ•ด ๋‹ค์–‘ํ•œ ์ƒํ™ฉ์—์„œ ํŠธ๋žœ์žญ์…˜์ด ์–ด๋–ป๊ฒŒ ๋™์ž‘ํ•˜๋Š”์ง€ ์‚ดํŽด๋ณผ ์˜ˆ์ •์ด๋‹ค. ๊ธ€์„ ์ฝ๋Š” ๋ถ„๋“ค๋„ ๊ฐ ์ƒํ™ฉ์—์„œ ๊ฒฐ๊ณผ๋ฅผ ์˜ˆ์ธกํ•ด ๋ณด๋ฉฐ ๋”ฐ๋ผ๊ฐ€๋ฉด ์ดํ•ด์— ๋„์›€์ด ๋  ๊ฒƒ ๊ฐ™๋‹ค.๋™์ผํ•œ ํด๋ž˜์Šค ๋‚ด์—์„œ์˜ ํŠธ๋žœ์žญ์…˜ ๋™์ž‘๋ณธ์ธ ๋ฉ”์„œ๋“œ์—์„œ ์˜ˆ์™ธ ๋ฐœ์ƒ ์‹œ ๋กค๋ฐฑ๋‹ค๋ฅธ ๋ฉ”์„œ๋“œ ํ˜ธ์ถœ ํ›„ ์˜ˆ์™ธ ๋ฐœ์ƒ ์‹œ ๋กค๋ฐฑ๋ณธ์ธ ๋ฉ”์„œ๋“œ์—์„œ try-catch๋กœ ์˜ˆ์™ธ ์ฒ˜๋ฆฌ ํ›„ ์ปค๋ฐ‹๋‹ค๋ฅธ ๋ฉ”์„œ๋“œ ํ˜ธ์ถœ ํ›„ ๋ณธ์ธ ๋ฉ”์„œ๋“œ์—์„œ try-catch๋กœ ์˜ˆ์™ธ ์ฒ˜๋ฆฌ ํ›„ ์ปค๋ฐ‹๋ณธ์ธ ๋ฉ”์„œ๋“œ์—์„œ noRollbackFor ์„ค์ • ํ›„ ์˜ˆ์™ธ ๋ฐœ์ƒ ์‹œ ์ปค๋ฐ‹noRollbackFor ์„ค์ •๋œ ๋‹ค๋ฅธ ๋ฉ”์„œ๋“œ.. 2024. 12. 22.
Spring ํŠธ๋žœ์žญ์…˜์€ ์–ธ์ œ ์–ด๋–ป๊ฒŒ ๋กค๋ฐฑ ๋ ๊นŒ? -1ํŽธ ๊ฐœ์š”์Šคํ”„๋ง์—์„œ @Transactional ์–ด๋…ธํ…Œ์ด์…˜์„ ์‚ฌ์šฉํ•˜๋ฉด ํŠธ๋žœ์žญ์…˜์ด ์ž๋™์œผ๋กœ ๊ด€๋ฆฌ๋œ๋‹ค. ๋กœ์ง์ด ์„ฑ๊ณต์ ์œผ๋กœ ์ฒ˜๋ฆฌ๋˜๋ฉด commit์„ ํ†ตํ•ด ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์— ๋ณ€๊ฒฝ ์‚ฌํ•ญ์ด ๋ฐ˜์˜๋˜๊ณ , ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ•˜๋ฉด rollback์„ ํ†ตํ•ด ๋ชจ๋“  ๋ณ€๊ฒฝ ์‚ฌํ•ญ์ด ์ทจ์†Œ๋œ๋‹ค. ๋‹ค๋งŒ ์ด๋Š” ๊ธฐ๋ณธ์ ์ธ ๊ฐœ๋…์œผ๋กœ ์ด๋ฒˆ ๊ธ€์—์„œ๋Š” ๋” ๋‚˜์•„๊ฐ€ ์„ธ๋ถ€์ ์œผ๋กœ ๋กค๋ฐฑ์ด ์ •ํ™•ํžˆ ์–ธ์ œ ๋ฐœ์ƒํ•˜๊ณ (1ํŽธ), ํŠน์ • ์ƒํ™ฉ์„ ์˜ˆ์‹œ๋กœ ํ•ด๋‹น ๋กœ์ง์ด ๋กค๋ฐฑ์ด ๋ ์ง€ ์•ˆ ๋ ์ง€์— ๋Œ€ํ•ด ๋งž์ถฐ๋ณด๋Š” ์‹(2ํŽธ)์œผ๋กœ ์•Œ์•„๋ณด๊ณ ์ž ํ•œ๋‹ค.  Check Exception, Unchecked Exception๋จผ์ € ์ž๋ฐ”์—์„œ๋Š” ์˜ˆ์™ธ๋ฅผ ํฌ๊ฒŒ ๋‹ค์Œ๊ณผ ๊ฐ™์ด Exception๊ณผ Error ๋‘ ๊ฐ€์ง€๋กœ ๋‚˜๋ˆ„๊ณ  ์žˆ๋‹ค.Exception์€ ์ž…๋ ฅ ๊ฐ’์— ๋Œ€ํ•œ ์ฒ˜๋ฆฌ๊ฐ€ ๋ถˆ๊ฐ€๋Šฅํ•˜๊ฑฐ๋‚˜ ํ”„๋กœ๊ทธ๋žจ ์‹คํ–‰ ์ค‘์— ์ฐธ์กฐ๋œ ๊ฐ’์ด ์ž˜๋ชป๋œ ๊ฒฝ์šฐ์ธ .. 2024. 10. 4.
[gradle] implementation, api ์ฐจ์ด ๊ฐœ์š”Gradle์—์„œ ์˜์กด์„ฑ์„ ์„ค์ •ํ•  ๋•Œ๋Š” compileOnly, runtimeOnly, implementation, api ๋“ฑ ์—ฌ๋Ÿฌ ๊ฐ€์ง€ ์˜ต์…˜์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค. ํŠนํžˆ api์™€ implementation์€ ์™ธ๋ถ€ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ํ”„๋กœ์ ํŠธ์— ์ถ”๊ฐ€ํ•  ๋•Œ ๊ฐ€์žฅ ์ž์ฃผ ์‚ฌ์šฉํ•˜๋Š” ๋‘ ๊ฐ€์ง€ ๋ฐฉ๋ฒ•์œผ๋กœ, ์ด ๋‘˜์€ ๋ชจ๋‘ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ์ถ”๊ฐ€ํ•˜๋Š” ๊ธฐ๋Šฅ์„ ์ œ๊ณตํ•˜์ง€๋งŒ ๊ฐ๊ธฐ ๋‹ค๋ฅธ ๋ฐฉ์‹์œผ๋กœ ๋™์ž‘ํ•˜๊ธฐ ๋•Œ๋ฌธ์— ์ฐจ์ด์ ์„ ์•Œ์•„๋‘๋ฉด ์ข‹๋‹ค.dependencies { api 'org.apache.httpcomponents:httpclient:4.5.7' implementation 'org.apache.commons:commons-lang3:3.5'}์ฐธ๊ณ ๋กœ ์ด์ „ Gradle ๋ฒ„์ „์—์„œ๋Š” implementation ํ‚ค์›Œ๋“œ๊ฐ€ ์—†์—ˆ๊ณ , ๋Œ€์‹  comp.. 2024. 9. 7.
[JPA] deleteAll(), deleteAllInBatch(), deleteInBatch() ์ •๋ฆฌ ๊ฐœ์š”Hibernate(JPA)์—์„œ๋Š” ๋ ˆ์ฝ”๋“œ๋ฅผ ์‚ญ์ œํ•  ์ˆ˜ ์žˆ๋Š” ์•„๋ž˜์˜ ๋‹ค์–‘ํ•œ ๋ฉ”์„œ๋“œ๋“ค์„ ์ง€์›ํ•œ๋‹ค.delete(),deleteById()deleteAll(), deleteAllById()deleteInBatch()deleteAllInBatch(), deleteAllByIdInBatch()๋‹ค์–‘ํ•œ ๋ฉ”์„œ๋“œ๋ฅผ ์ œ๊ณตํ•˜๋Š” ๊ฒƒ์€ ์ข‹์ง€๋งŒ, ๋„ค์ด๋ฐ๋งŒ ๋ณด๊ณ  ํ˜ผ๋ž€์Šค๋Ÿฌ์šด ๊ฒƒ๋“ค์ด ๋ช‡๋ช‡ ์žˆ๋‹ค. ๋Œ€ํ‘œ์ ์œผ๋กœ deleteInBatch()์™€ deleteAllInBatch(), ๊ทธ๋ฆฌ๊ณ  deleteAll()๊ณผ deleteAllInBatch()์™€ ๊ฐ™์€ ๋ฉ”์„œ๋“œ๋“ค์ด๋‹ค.์ด๋ฒˆ ๊ฒŒ์‹œ๊ธ€์—์„œ๋Š” ์œ„ ๋ฉ”์„œ๋“œ๋“ค์ด ์‹ค์ œ๋กœ ์–ด๋–ป๊ฒŒ ์‚ญ์ œ๋ฅผ ์ฒ˜๋ฆฌํ•˜๋Š”์ง€๋ฅผ ์‚ดํŽด๋ณผ ๊ฒƒ์ด๊ณ , ์—ฐ๊ด€๊ด€๊ณ„๊ฐ€ ์—†๋Š” ๊ฒฝ์šฐ์™€ ์—ฐ๊ด€๊ด€๊ณ„๊ฐ€ ์žˆ๋Š” ๊ฒฝ์šฐ๋กœ ๋‚˜๋ˆ„์–ด ์‚ญ์ œ ๋™์ž‘์„ ๋ถ„์„ํ•ด ๋ณผ ๊ฒƒ์ด๋‹ค.  ์‚ฌ์ „ ์„ธํŒ…DB.. 2024. 8. 12.
๋‹จ๋ฐฉํ–ฅ @OneToMany์˜ ๋ฌธ์ œ์  ๊ฐœ์š”JPA๋ฅผ ํ•™์Šตํ•˜๋‹ค ๋ณด๋ฉด @OneToMany๋ฅผ ์‚ฌ์šฉํ•  ๋•Œ ๋‹จ๋ฐฉํ–ฅ๋ณด๋‹ค๋Š” ์–‘๋ฐฉํ–ฅ ๋งคํ•‘์„ ์‚ฌ์šฉํ•˜๋ผ๋Š” ๋ง์„ ์ž์ฃผ ๋“ฃ๊ฒŒ ๋œ๋‹ค.์™œ ๊ทธ๋Ÿฐ์ง€ ์ดํ•ดํ•˜๊ธฐ ์œ„ํ•ด ๋‹จ๋ฐฉํ–ฅ @OneToMany๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๋‘ ๊ฐ€์ง€ ๋ฐฉ๋ฒ•์„ ์‚ฌ์šฉํ•˜์—ฌ ๋ฌธ์ œ์ ์— ๋Œ€ํ•ด ์‚ดํŽด๋ณด๊ณ , ์–‘๋ฐฉํ–ฅ์„ ์‚ฌ์šฉํ–ˆ์„ ๋•Œ ์–ด๋–ค ์ ์ด ๊ฐœ์„ ๋˜๋Š”์ง€ ์•Œ์•„๋ณด์ž๋งคํ•‘ ํ…Œ์ด๋ธ”์„ ์‚ฌ์šฉํ•œ ๋‹จ๋ฐฉํ–ฅ @OneToMany ๋™์ž‘ ๊ณผ์ •@JoinColumn ์‚ฌ์šฉํ•œ ๋‹จ๋ฐฉํ–ฅ @OneToMany  ๋™์ž‘ ๊ณผ์ •์–‘๋ฐฉํ–ฅ @OneToMany๋ฅผ ์‚ฌ์šฉํ–ˆ์„ ๋•Œ์˜ ๋™์ž‘ ๊ณผ์ • 1. ๋งคํ•‘ ํ…Œ์ด๋ธ” ์‚ฌ์šฉ๋งคํ•‘ ํ…Œ์ด๋ธ”์„ ์ด์šฉํ•œ @OneToMany ์—”ํ‹ฐํ‹ฐ ์„ค๊ณ„ ์˜ˆ์‹œ๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™๋‹ค.@Entity@NoArgsConstructor(access = lombok.AccessLevel.PROTECTED)public class Book { @I.. 2024. 7. 26.
@TransactionalEventListener ์‚ฌ์šฉ ์‹œ ์—…๋ฐ์ดํŠธ ์•ˆ๋  ๋•Œ ๋ฌธ์ œ ์ƒํ™ฉ@Service@RequiredArgsConstructorpublic class CurrentValueChangeService { private final ExampleRepository exampleRepository; private final ApplicationEventPublisher applicationEventPublisher; @Transactional public void changeValue(String value) { Example example = exampleRepository.find(1L); String beforeValue = example.getCurrentValue(); example.updateCurren.. 2024. 7. 3.