์ข‹์€ ์ด์Šˆ ๋ฆฌํฌํŠธ๋Š” ์–ด๋–ป๊ฒŒ ๋งŒ๋“ค์–ด์ง€๋Š”๊ฐ€New

๐Ÿ“š
Backend
2026.09.22

๐Ÿ“š Overview

์ง€๋‚œ โ€œ์กฐ์šฉํžˆ ๋น„์–ด๋ฒ„๋ฆฐ ๊ฐ’ ํ•˜๋‚˜์—์„œ ์‹œ์ž‘ํ•œ ORM ๋ฉ”์ด์ € ์—…๊ทธ๋ ˆ์ด๋“œ ๊ฒ€์ฆ ์ „๋žตโ€ ํฌ์ŠคํŒ…์„ ์ด๋ ‡๊ฒŒ ๋งบ์—ˆ๋‹ค.

๊ฐ™์€ ์‚ฌ๋ก€์˜ ์—…์ŠคํŠธ๋ฆผ ์ด์Šˆ๋Š” ์ฐพ์ง€ ๋ชปํ–ˆ๋‹ค. ์žฌํ˜„ ์กฐ๊ฑด์„ ์ขํžˆ๊ณ  โ€œ๋ฒ„๊ทธโ€๋กœ ๋ณผ์ง€ โ€œ์ง„๋‹จ ๋ฉ”์‹œ์ง€ ๊ฐœ์„  ์š”์ฒญโ€์œผ๋กœ ๋ณผ์ง€ ์Šค์Šค๋กœ ๋จผ์ € ๊ฒฐ๋ก ์„ ๋‚ธ ๋’ค, ์ตœ์†Œ ์žฌํ˜„ ์ €์žฅ์†Œ์™€ ํ•จ๊ป˜ ์ œ๋ณดํ•ด๋ณผ ์ƒ๊ฐ์ด๋‹ค.

์–ด์ œ ๊ทธ ์ด์Šˆ๋ฅผ ์˜ฌ๋ ธ๋‹ค.

  • 09-21 13:51 โ€” ์ด์Šˆ ๋“ฑ๋ก (mikro-orm#8292)
  • 09-21 14:12 โ€” ๋‹ค๋ฅธ ์ปจํŠธ๋ฆฌ๋ทฐํ„ฐ๊ฐ€ PR ๋“ฑ๋ก (mikro-orm#8293), ์ด์Šˆ๋กœ๋ถ€ํ„ฐ 21๋ถ„
  • 09-22 02:25 โ€” ๋ฉ”์ธํ…Œ์ด๋„ˆ ๋จธ์ง€, ์ด์Šˆ ์ข…๋ฃŒ

์ •์ž‘ ๋‚ด๊ฐ€ ์“ด ์ฝ”๋“œ๋Š” ํ•œ ์ค„๋„ ์—†๋‹ค. ๊ณ ์นœ ๊ฒƒ์€ ๋‹ค๋ฅธ ์‚ฌ๋žŒ์ด๊ณ , ๋‚˜๋Š” ์žฌํ˜„๊ณผ ์ด์Šˆ ๋ณธ๋ฌธ๋งŒ ์ผ๋‹ค.

์ด ๊ธ€์€ ์‚ฌ๋‚ด์—์„œ ์šฐํšŒ๋กœ ๋ฎ์–ด๋‘” ๋ฌธ์ œ๋ฅผ ์—…์ŠคํŠธ๋ฆผ ์ด์Šˆ๋กœ ์˜ฎ๊ธฐ๊ธฐ๊นŒ์ง€์˜ ๊ธฐ๋ก์ด๋‹ค. ๊ทธ๋ฆฌ๊ณ  ์™œ ์ด ์ด์Šˆ๊ฐ€ 21๋ถ„ ๋งŒ์— PR๋กœ ์ด์–ด์กŒ๋Š”์ง€, ๊ทธ ์ด์œ ๋ผ๊ณ  ์ƒ๊ฐํ•˜๋Š” ๊ฒƒ๋“ค์„ ๋‚จ๊ธด๋‹ค.



1. ์šฐํšŒ์™€ ์ œ๋ณด๋ฅผ ๋ถ„๋ฆฌํ•œ ์ด์œ 


๋ฌธ์ œ ์ž์ฒด๋Š” ์ง€๋‚œ ๊ธ€์—์„œ ์ •๋ฆฌํ–ˆ๋‹ค. ์ž„๋ฒ ๋””๋“œ ๊ฐ’ ๊ฐ์ฒด์˜ ํ”„๋กœํผํ‹ฐ ์ด๋ฆ„(User.password)๊ณผ ๊ทธ ๊ฐ’์ด ์ €์žฅ๋˜๋Š” ์ปฌ๋Ÿผ ์ด๋ฆ„(password)์ด ๊ฐ™์„ ๋•Œ, JOIN ์œผ๋กœ ํ•จ๊ป˜ ๋ถˆ๋Ÿฌ์˜ค๋Š” ๊ฒฝ๋กœ์—์„œ๋งŒ ๋งคํ•‘์ด ๊นจ์ง€๋Š” ํ˜„์ƒ์ด๋‹ค.

๋‹น์‹œ ์„ ํƒํ•œ ํ•ด๋ฒ•์€ ์ด๋ฆ„ ์ถฉ๋Œ ์ž์ฒด๋ฅผ ์—†์• ๋Š” ๊ฒƒ์ด์—ˆ๋‹ค. ํ”„๋กœํผํ‹ฐ ์ด๋ฆ„์„ hashedPassword ๋กœ ๋ฐ”๊พธ๊ณ  fieldName ์„ ๋”ฐ๋กœ ์ค˜์„œ, DB ์Šคํ‚ค๋งˆ๋Š” ๊ทธ๋Œ€๋กœ ๋‘” ์ฑ„ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ์ฝ”๋“œ ์•ˆ์—์„œ๋งŒ ๋๋ƒˆ๋‹ค.

์ด ์šฐํšŒ๋Š” ์—…๊ทธ๋ ˆ์ด๋“œ๋ฅผ ๋ง‰์ง€ ์•Š๊ธฐ ์œ„ํ•œ ์„ ํƒ์ด์—ˆ๋‹ค. ๋ฌธ์ œ๋ฅผ ์ดํ•ดํ•œ ๊ฒƒ์€ ์•„๋‹ˆ์—ˆ๋‹ค. ์›์ธ์€ ์—ฌ์ „ํžˆ ORM ์•ˆ์— ์žˆ์—ˆ๊ณ , ์šฐ๋ฆฌ๋Š” ๊ทธ ์œ„์— ์ด๋ฆ„ ํ•˜๋‚˜๋ฅผ ๋ฎ์–ด๋‘” ์ƒํƒœ์˜€๋‹ค.

๊ทธ๋ž˜์„œ ์šฐํšŒ์™€ ์ œ๋ณด๋ฅผ ํ•˜๋‚˜์˜ ์ž‘์—…์œผ๋กœ ๋ฌถ์ง€ ์•Š์•˜๋‹ค. ์šฐํšŒ๋Š” ๋ฐฐํฌ๊นŒ์ง€ ๋๋‚ด๊ณ , ์ œ๋ณด๋Š” ๊ทธ ๋’ค์— ๋”ฐ๋กœ ์ง„ํ–‰ํ–ˆ๋‹ค. ์šฐํšŒ๊ฐ€ ์ด๋ฏธ ๋ฐฐํฌ๋˜์–ด ์žˆ์œผ๋‹ˆ ์ œ๋ณด๋ฅผ ์„œ๋‘˜๋Ÿฌ์•ผ ํ•  ์ด์œ ๊ฐ€ ์—†์—ˆ๊ณ , ๊ทธ๋งŒํผ ์žฌํ˜„์„ ๋‹ค๋“ฌ์„ ์‹œ๊ฐ„์ด ์ƒ๊ฒผ๋‹ค.

๋˜๋Œ๋ฆด ๊ณ„ํš์ด ํ•„์š”ํ–ˆ๋˜ ๊ฒƒ๋„ ์ด์œ ์˜€๋‹ค. hashedPassword ๋ผ๋Š” ์ด๋ฆ„๊ณผ fieldName: '_password' ๋Š” ์›๋ž˜ ํ•„์š” ์—†๋˜ ๊ฒƒ์ด๋‹ค. ์ด ํ”์ ์„ ์ง€์šฐ๋ ค๋ฉด ์—…์ŠคํŠธ๋ฆผ์ด ๊ณ ์ณ์ง€๋Š” ์ˆ˜๋ฐ–์— ์—†์—ˆ๋‹ค.



2. ์žฌํ˜„์„ ๋‚จ์˜ ์ผ๋กœ ๋งŒ๋“ค์ง€ ์•Š๊ธฐ


MikroORM ์€ ์ด์Šˆ ํ…œํ”Œ๋ฆฟ์—์„œ ์žฌํ˜„ ์ €์žฅ์†Œ๋ฅผ ์š”๊ตฌํ•˜๊ณ , ๊ทธ์™€ ํ•จ๊ป˜ mikro-orm/reproduction ์ด๋ผ๋Š” ์žฌํ˜„์šฉ ๋ฒ ์ด์Šค ์ €์žฅ์†Œ๋ฅผ ์ œ๊ณตํ•œ๋‹ค.

๋‚˜๋Š” ์ด ์ €์žฅ์†Œ๋ฅผ fork ํ•ด์„œ JH8459/reproduction ์„ ๋งŒ๋“ค๊ณ , ์ฆ์ƒ์„ ์žฌํ˜„ํ•˜๋Š” ์ปค๋ฐ‹ ํ•˜๋‚˜๋งŒ ์–น์—ˆ๋‹ค.

fork ๋ฅผ ํƒํ•œ ๊ฒƒ์€ ํŽธํ•ด์„œ๊ฐ€ ์•„๋‹ˆ์—ˆ๋‹ค. ๋ฒ ์ด์Šค์˜ ์ปค๋ฐ‹ ์ด๋ ฅ์„ ๋ณด๋ฉด ๋ฉ”์ธํ…Œ์ด๋„ˆ๊ฐ€ ์ง์ ‘ ์ •๋ฆฌํ•ด๋‘” ๊ฒƒ์ด๊ณ , ์ปค๋ฐ‹ ๋ฉ”์‹œ์ง€์— ๊ทธ ์˜๋„๊ฐ€ ์ ํ˜€ ์žˆ๋‹ค.

๋ฉ”์ธํ…Œ์ด๋„ˆ B4nan(Martin Adรกmek)์ด ์žฌํ˜„ ๋ฒ ์ด์Šค๋ฅผ ํ•œ ํŒŒ์ผ๋กœ ์ •๋ฆฌํ•ด๋‘” ์ปค๋ฐ‹์ด๋‹ค.


์žฌํ˜„ ์ฝ”๋“œ๋ฅผ ORM ๋ณธ์ฒด์˜ ํ…Œ์ŠคํŠธ๋กœ ์˜ฎ๊ธธ ๋•Œ ์–ด์ฐจํ”ผ ํ•ด์•ผ ํ•˜๋Š” ์†์งˆ์„ ๋ฏธ๋ฆฌ ํ•ด๋‘” ๋ฒ ์ด์Šค๋ผ๋Š” ๋œป์ด๋‹ค. ํ…Œ์ŠคํŠธ ๋Ÿฌ๋„ˆ, ๋“œ๋ผ์ด๋ฒ„, ์—”ํ‹ฐํ‹ฐ ์ •์˜ ๋ฐฉ์‹์ด ๋ชจ๋‘ ๋ณธ์ฒด ํ…Œ์ŠคํŠธ์™€ ๊ฐ™์€ ๋ชจ์–‘์œผ๋กœ ๋งž์ถฐ์ ธ ์žˆ๋‹ค.

๊ทธ ์œ„์— ์ปค๋ฐ‹ ํ•˜๋‚˜๋งŒ ์˜ฌ๋ฆฌ๋ฉด ๋ฐ›๋Š” ์ชฝ์€ ์ €์žฅ์†Œ ์ „์ฒด๋ฅผ ํ›‘์„ ํ•„์š”๊ฐ€ ์—†๋‹ค. ๊ทธ ์ปค๋ฐ‹๋งŒ ๋ณด๋ฉด ์žฌํ˜„ ์กฐ๊ฑด์ด ๋‹ค ๋‚˜์˜จ๋‹ค. ์‹ค์ œ๋กœ ์ด๋ฒˆ PR ์˜ ํšŒ๊ท€ ํ…Œ์ŠคํŠธ๋Š” ๊ทธ ํ˜•ํƒœ๋ฅผ ๊ทธ๋Œ€๋กœ ์ด์–ด๋ฐ›์•„ tests/issues/GH8292.test.ts ๋กœ ๋“ค์–ด๊ฐ”๋‹ค.

๋ฒ ์ด์Šค README ์— ์ ํžŒ ํžŒํŠธ๋Š” ์‚ฌ์‹ค์ƒ ์ฑ„์  ๊ธฐ์ค€์ด๋‹ค.

  • ํ•œ ๋ฒˆ์— ํ•˜๋‚˜์˜ ๋ฌธ์ œ๋งŒ ์žฌํ˜„ํ•  ๊ฒƒ
  • ํ…Œ์ŠคํŠธ๋Š” ์ž๊ธฐ์™„๊ฒฐ์ ์ผ ๊ฒƒ โ€” ๋ฐ์ดํ„ฐ ์ค€๋น„๊นŒ์ง€ ํ…Œ์ŠคํŠธ ์•ˆ์—์„œ
  • CLI ๋ฅผ ์“ฐ์ง€ ๋ง๊ณ  ์ „๋ถ€ ํ”„๋กœ๊ทธ๋žจ์œผ๋กœ ํ•  ๊ฒƒ
  • ๊ด€๋ จ ์—†๋Š” ๊ฒƒ์€ ์ „๋ถ€ ์ œ๊ฑฐํ•  ๊ฒƒ
  • ํ…Œ์ŠคํŠธ์˜ ์ค‘๋ณต์€ ๊ดœ์ฐฎ๋‹ค, ๋ณต์žกํ•œ ์ถ”์ƒํ™”๋ณด๋‹ค ๋‚ซ๋‹ค
  • ์ฃผ์„๋„ ์ข‹์ง€๋งŒ ๋‹จ์–ธ์ด ๋” ์ข‹๋‹ค

์‹ค์ œ ์—”ํ‹ฐํ‹ฐ๋Š” ํ•„๋“œ๊ฐ€ ์ˆ˜์‹ญ ๊ฐœ์˜€์ง€๋งŒ ์žฌํ˜„์—์„œ๋Š” User / Password / Profile ์„ธ ๊ฐœ๋งŒ ๋‚จ๊ฒผ๋‹ค. ๋“œ๋ผ์ด๋ฒ„๋„ ์ธ๋ฉ”๋ชจ๋ฆฌ SQLite ๋กœ ๋ฐ”๊ฟจ๋‹ค. ๋ฌธ์ œ์˜ ์กฐ๊ฑด์€ ์ž„๋ฒ ๋””๋“œ ํ”„๋กœํผํ‹ฐ ์ด๋ฆ„๊ณผ ์ž์‹ ์ปฌ๋Ÿผ ์ด๋ฆ„์ด ๊ฐ™๋‹ค๋Š” ๊ฒƒ ํ•˜๋‚˜์˜€๊ณ , ๋‚˜๋จธ์ง€๋Š” ์žฌํ˜„์„ ํ๋ฆฌ๋Š” ์žก์Œ์ด์—ˆ๋‹ค.

๊ฐ€์žฅ ์‹ ๊ฒฝ ์“ด ๊ฒƒ์€ ๋”ฐ๋กœ ์žˆ๋‹ค. ํ†ต๊ณผํ•˜๋Š” ํ…Œ์ŠคํŠธ๋ฅผ ์ผ๋ถ€๋Ÿฌ ํ•จ๊ป˜ ๋„ฃ์—ˆ๋‹ค.

test('direct load hydrates embedded', async () => { ... });          // ํ†ต๊ณผ
test('select-in populate hydrates embedded', async () => { ... });   // ํ†ต๊ณผ

// fails in v7: Cannot use 'as u1__password' alias on embedded property 'u1.password'
test('joined populate hydrates embedded', async () => { ... });      // ์‹คํŒจ

// fails in v6: Empty .update() call detected! Table: `user`. Columns: .
test('flush after joined populate issues no user update', async () => { ... });  // ์‹คํŒจ

์‹คํŒจํ•˜๋Š” ์ผ€์ด์Šค๋งŒ ์˜ฌ๋ฆฌ๋ฉด ์ฝ๋Š” ์‚ฌ๋žŒ์˜ ์ฒซ ์งˆ๋ฌธ์€ ์„ค์ •์ด ์ž˜๋ชป๋œ ๊ฒŒ ์•„๋‹ˆ๋ƒ๋Š” ๊ฒƒ์ด ๋œ๋‹ค. ๊ทธ ์งˆ๋ฌธ์— ๋‹ตํ•˜๋ ค๋ฉด ์™•๋ณต์ด ํ•œ ๋ฒˆ ๋” ํ•„์š”ํ•˜๊ณ , ๊ทธ๋ ‡๊ฒŒ ๋˜๋ฉด ์ด์Šˆ๋Š” ๋Œ€๊ฐœ ๋’ค๋กœ ๋ฐ€๋ฆฐ๋‹ค.

๊ฐ™์€ ์—”ํ‹ฐํ‹ฐ์™€ ๊ฐ™์€ ๋ฐ์ดํ„ฐ๋กœ ํ†ต๊ณผํ•˜๋Š” ๊ฒฝ๋กœ๋ฅผ ๋‚˜๋ž€ํžˆ ๋‘๋ฉด ๊ทธ ์งˆ๋ฌธ์ด ๋‚˜์˜ค์ง€ ์•Š๋Š”๋‹ค. ์—”ํ‹ฐํ‹ฐ ์ •์˜๊ฐ€ ์•„๋‹ˆ๋ผ ๋กœ๋”ฉ ์ „๋žต๋งŒ ๋‹ค๋ฅด๋‹ค๋Š” ๊ฒŒ ํ…Œ์ŠคํŠธ ์ด๋ฆ„์—์„œ ์ด๋ฏธ ๋ณด์ธ๋‹ค.

fork ๋ถ€ํ„ฐ ์ด์Šˆ ๋“ฑ๋ก๊นŒ์ง€๋Š” 11๋ถ„์ด ๊ฑธ๋ ธ๋‹ค. ์•ž์—์„œ ์žฌํ˜„์„ ๋‹ค๋“ฌ์„ ์‹œ๊ฐ„์ด ์ƒ๊ฒผ๋‹ค๊ณ  ์ ์€ ๊ฒƒ๊ณผ ์–ด๊ธ‹๋‚˜ ๋ณด์ด์ง€๋งŒ, ์šฐํšŒ๋ฅผ ๋งŒ๋“œ๋Š” ๊ณผ์ •์—์„œ ์กฐ๊ฑด์„ ์ด๋ฏธ ์ขํ˜€๋’€๊ธฐ ๋•Œ๋ฌธ์— ์ €์žฅ์†Œ ์ž‘์—… ์ž์ฒด๋Š” ์งง๊ฒŒ ๋๋‚ฌ๋‹ค.



3. ์ด์Šˆ ๋ณธ๋ฌธ์— ๋ฌด์—‡์„ ์ ์—ˆ๋‚˜


๊ฐ€์žฅ ์•ž์— ๋‘” ๊ฒƒ์€ v6 ์™€ v7 ์˜ ์ฆ์ƒ์ด ๋‹ค๋ฅด๋‹ค๋Š” ์ ์ด์—ˆ๋‹ค. ๊ฐ™์€ ๋งคํ•‘์ธ๋ฐ v7 ์€ ์˜ˆ์™ธ๋ฅผ ๋˜์ง€๊ณ , v6 ์€ ์กฐ์šฉํžˆ ๋นˆ UPDATE ๋ฅผ ๋งŒ๋“ ๋‹ค.

# v7 โ€” joined populate ์ž์ฒด๊ฐ€ ์‹คํŒจ
DriverException: Cannot use 'as u1__password' alias on embedded property 'u1.password'
because it expands to multiple columns.

# v6 โ€” ์กฐํšŒ๋Š” ๋˜์ง€๋งŒ, ์ดํ›„ flush ์—์„œ
Empty .update() call detected! Update data does not contain any values to update. Table: `user`. Columns: .

ํ•œ์ชฝ๋งŒ ๋ณด๋ฉด ์›๋ž˜ ์ง€์›ํ•˜์ง€ ์•Š๋Š” ์„ค๊ณ„๋กœ ์ฝํžŒ๋‹ค. ๋ฒ„์ „์— ๋”ฐ๋ผ ์ฆ์ƒ์ด ๊ฐˆ๋ฆฐ๋‹ค๋Š” ์ ์ด ๊ทธ๋ ‡์ง€ ์•Š๋‹ค๋Š” ์ชฝ์˜ ๊ทผ๊ฑฐ๊ฐ€ ๋๋‹ค๊ณ  ์ƒ๊ฐํ•œ๋‹ค.

๊ทธ ๋’ค์— ํ™•์ธํ•œ ๋ฒ”์œ„๋ฅผ ์ ์—ˆ๋‹ค. next(7.2.1-dev.24)์™€ 7.2.1, 7.2.0 ์—์„œ ์‹คํŒจํ•˜๊ณ , 6.6.16 ์—์„œ๋Š” joined populate ๋Š” ํ†ต๊ณผํ•˜๋Š”๋ฐ flush ๋งŒ ์‹คํŒจํ–ˆ๋‹ค. sqlite ์™€ mariadb 11.4 ์–‘์ชฝ ๊ฒฐ๊ณผ๊ฐ€ ๊ฐ™์•˜๋‹ค. ๋น„์Šทํ•ด ๋ณด์ด๋Š” ๊ธฐ์กด ์ด์Šˆ(#8271, #8272)๋„ ๋จผ์ € ์ฐพ์•„์„œ, ๊ทธ ์ˆ˜์ •์ด ๋“ค์–ด๊ฐ„ next ์—์„œ๋„ ์žฌํ˜„๋œ๋‹ค๋Š” ๊ฒƒ์„ ํ•จ๊ป˜ ์ ์—ˆ๋‹ค. ๋“œ๋ผ์ด๋ฒ„ ๋ฌธ์ œ์ธ์ง€ ์ด๋ฏธ ๊ณ ์ณ์ง„ ๋ฌธ์ œ์ธ์ง€ ํ™•์ธํ•˜๋Š” ๋ชซ์„ ๋„˜๊ธฐ์ง€ ์•Š์œผ๋ ค๋Š” ์˜๋„์˜€๋‹ค.

์š”๊ตฌ๋Š” ์ตœ์†Œ๋กœ ์ ์—ˆ๋‹ค. ๋ฉ”์ธํ…Œ์ด๋„ˆ๋Š” ์ „๋ถ€ํ„ฐ ๋‹จ์ผ ์†์„ฑ ์ž„๋ฒ ๋”๋ธ”๋ณด๋‹ค ์ปค์Šคํ…€ ํƒ€์ž…์„ ๊ถŒ๊ณ ํ•ด์™”๊ณ , ๊ทธ ์ƒํƒœ์—์„œ ์šฐ๋ฆฌ ๋งคํ•‘์ด ๋™์ž‘ํ•˜๊ฒŒ ํ•ด๋‹ฌ๋ผ๊ณ  ์“ฐ๋ฉด ๊ถŒ๊ณ ๋ฅผ ๋ฌด์‹œํ•œ ์„ค๊ณ„๋ฅผ ๋– ๋ฐ›์ณ ๋‹ฌ๋ผ๋Š” ์š”์ฒญ์ด ๋œ๋‹ค. ๊ทธ๋ž˜์„œ ๊ฐ™์€ ๋งคํ•‘์ด ๋ฒ„์ „์— ๋”ฐ๋ผ ๋‹ค๋ฅด๊ฒŒ ์‹คํŒจํ•˜๊ณ  ์—๋Ÿฌ ๋ฉ”์‹œ์ง€์—์„œ ์›์ธ๊นŒ์ง€ ๊ฐ€๋Š” ๊ฑฐ๋ฆฌ๊ฐ€ ๋ฉ€๋‹ค๋Š” ๊ฒƒ๋งŒ ๋‚จ๊ฒผ๋‹ค. ๋ณ„์นญ ํ•ด์„ ๋‹จ๊ณ„์—์„œ u1.password ๊ฐ€ ์ปฌ๋Ÿผ์ด ์•„๋‹ˆ๋ผ ์ž„๋ฒ ๋””๋“œ ํ”„๋กœํผํ‹ฐ๋กœ ํ’€๋ฆฌ๋Š” ๊ฒƒ ๊ฐ™๋‹ค๋Š” ์ง์ž‘์€ ์ ์—ˆ์ง€๋งŒ ๋‹จ์ •ํ•˜์ง€๋Š” ์•Š์•˜๋‹ค. ์ด๋ฆ„์„ ๋ฐ”๊พธ๋ฉด ์‚ฌ๋ผ์ง„๋‹ค๋Š” ์šฐํšŒ์ฑ…๋„ ๊ฐ™์ด ์ ์–ด๋’€๋‹ค.



4. 21๋ถ„ ๋’ค์— ์˜จ PR, ๊ทธ๋ฆฌ๊ณ  ๋‚ด ์‹ ๊ณ ๋ณด๋‹ค ๋„“์—ˆ๋˜ ์ˆ˜์ •


PR ์€ ์ด์Šˆ ๋“ฑ๋ก 21๋ถ„ ๋’ค์— ์˜ฌ๋ผ์™”๊ณ , ๊ฐ™์€ ๋‚  ๋ฉ”์ธํ…Œ์ด๋„ˆ๊ฐ€ ๋จธ์ง€ํ–ˆ๋‹ค. ๋ณ€๊ฒฝ์€ QueryBuilder ํ•œ ๊ณณ, 16์ค„์ด์—ˆ๋‹ค.

// ์กฐ์ธ ์ „๋žต์€ ์ปฌ๋Ÿผ ์ด๋ฆ„์œผ๋กœ select ํ•˜๋Š”๋ฐ, ๊ทธ ์ด๋ฆ„์ด ์ธ๋ผ์ธ ์ž„๋ฒ ๋””๋“œ ํ”„๋กœํผํ‹ฐ ์ด๋ฆ„๊ณผ ์ถฉ๋Œํ•  ์ˆ˜ ์žˆ๋‹ค
const shadowed =
  customAlias &&
  prop?.kind === ReferenceKind.EMBEDDED &&
  (this.#state.aliases[a]?.meta ?? this.mainAlias.meta).props.some(
    p => (p.kind !== ReferenceKind.EMBEDDED || p.object) && p.fieldNames?.includes(f),
  );

if (prop?.kind === ReferenceKind.EMBEDDED && !shadowed) {
  // ๊ธฐ์กด์ฒ˜๋Ÿผ ์—ฌ๋Ÿฌ ์ปฌ๋Ÿผ์œผ๋กœ ํŽผ์น˜๊ณ , ๋ณ„์นญ์ด ๋ถ™์–ด ์žˆ์œผ๋ฉด ๊ฑฐ๋ถ€ํ•œ๋‹ค
}

๋ณ„์นญ์ด ๋ถ™์€ select ์˜ ์ด๋ฆ„์ด ์—”ํ‹ฐํ‹ฐ์˜ ์‹ค์ œ ์ปฌ๋Ÿผ๊ณผ ์ผ์น˜ํ•˜๋ฉด, ์ž„๋ฒ ๋””๋“œ ํ”„๋กœํผํ‹ฐ๊ฐ€ ์•„๋‹ˆ๋ผ ๊ทธ ์ปฌ๋Ÿผ์œผ๋กœ ํ•ด์„ํ•˜๋„๋ก ๋ฐ”๊พผ ๊ฒƒ์ด๋‹ค. ๋ณ„์นญ์ด ์—†์œผ๋ฉด ์ข…์ „๋Œ€๋กœ ํ”„๋กœํผํ‹ฐ ์ „์ฒด๋ฅผ ํŽผ์นœ๋‹ค. ๋‚ด๊ฐ€ ์ง์ž‘ํ–ˆ๋˜ ์ง€์ ๊ณผ ๊ฐ™์€ ์ž๋ฆฌ์˜€๋‹ค.

์ˆ˜์ •์ด ๋‚ด๊ฐ€ ์‹ ๊ณ ํ•œ ๊ฒƒ๋ณด๋‹ค ๋„“์—ˆ๋‹ค๋Š” ์ ์ด ํฅ๋ฏธ๋กœ์› ๋‹ค. ๊ฐ™์€ ๋ถ„๊ธฐ์—์„œ ๋‘ ๊ฐ€์ง€๊ฐ€ ๋” ๊ณ ์ณ์กŒ๋‹ค.

  • persist: false ์ธ ์ž์‹์„ ๊ฐ€์ง„ ์ธ๋ผ์ธ ์ž„๋ฒ ๋”๋ธ”์ด ์ปฌ๋Ÿผ ์ „๊ฐœ ๊ณผ์ •์—์„œ ๊นจ์ง€๋˜ ๋ฌธ์ œ
  • ์ „๊ฐœ๋œ ์ปฌ๋Ÿผ์— ์š”์ฒญ๋œ ์กฐ์ธ ๋ณ„์นญ์ด ๋ถ™์ง€ ์•Š์•„, ์กฐ์ธํ•ด์„œ ์ฝ์–ด์•ผ ํ•  ์ž„๋ฒ ๋”๋ธ”์„ ๋ฉ”์ธ ํ…Œ์ด๋ธ”์—์„œ ์ฝ์–ด์˜ค๋˜ ๋ฌธ์ œ

๋‘ ๋ฒˆ์งธ๊ฐ€ ๋ˆˆ์— ๊ฑธ๋ ธ๋‹ค. ์˜ˆ์™ธ๋„ ์—†๊ณ  ๊ฐ’๋„ ์ฑ„์›Œ์ง€๋Š”๋ฐ ์ถœ์ฒ˜๊ฐ€ ํ‹€๋ฆฐ ํ˜•ํƒœ๋‹ค. ๋‚ด๊ฐ€ ์˜ฌ๋ฆฐ ๋ฌธ์ œ๋Š” ๊ทธ๋ž˜๋„ ์‹œ๋„๋Ÿฝ๊ฒŒ ํ„ฐ์ง€๊ธฐ๋Š” ํ–ˆ๋Š”๋ฐ, ์ด์ชฝ์€ ์กฐ์šฉํžˆ ํ‹€๋ฆฐ ๊ฐ’์„ ์ค€๋‹ค. ์ œ๋ณดํ•˜์ง€ ์•Š์•˜๋˜ ๋ฒ„๊ทธ๊ฐ€ ๊ฐ™์€ ๋ถ„๊ธฐ ์•ˆ์— ํ•จ๊ป˜ ์žˆ์—ˆ๋˜ ์…ˆ์ด๋‹ค.

๋จธ์ง€๋œ ํšŒ๊ท€ ํ…Œ์ŠคํŠธ๋„ ๋‚ด ์žฌํ˜„๋ณด๋‹ค ๋„“๋‹ค. ๋‹จ์ผ ์ปฌ๋Ÿผ ์ž„๋ฒ ๋”๋ธ”๋ฟ ์•„๋‹ˆ๋ผ ๋‹ค์ค‘ ์ปฌ๋Ÿผ ์ž„๋ฒ ๋”๋ธ”, ์ค‘์ฒฉ ์ž„๋ฒ ๋”๋ธ”, persist: false ์ž์‹, ์ž„๋ฒ ๋”๋ธ” ์ปฌ๋Ÿผ๊ณผ ์ด๋ฆ„์ด ๊ฒน์น˜๋Š” ํ‰๋ฒ”ํ•œ ์Šค์นผ๋ผ ํ”„๋กœํผํ‹ฐ๊นŒ์ง€ ํ•œ ํŒŒ์ผ์— ๋“ค์–ด๊ฐ”๋‹ค. ๋‚ด ์žฌํ˜„ ๋„ค ์ค„์€ ๊ทธ ํ˜•ํƒœ์˜ ์”จ์•— ์ •๋„์˜€๋‹ค.

๋‚จ์€ ์ผ์€ ์šฐํšŒ๋ฅผ ๋˜๋Œ๋ฆฌ๋Š” ๊ฒƒ์ด๋‹ค. ์ˆ˜์ •์ด ๋ฆด๋ฆฌ์Šค์— ์‹ค๋ฆฌ๋ฉด hashedPassword ๋ฅผ ์›๋ž˜ ์ด๋ฆ„์œผ๋กœ ๋˜๋Œ๋ฆด ์ˆ˜ ์žˆ๋‹ค. ๋˜๋Œ๋ฆฌ๋Š” ๊ธฐ์ค€์€ ๋ฒ„์ „์„ ์˜ฌ๋ ธ๋‹ค๋Š” ์‚ฌ์‹ค์ด ์•„๋‹ˆ๋ผ, ์กฐ์ธ ์ „๋žต์œผ๋กœ ๋ถˆ๋Ÿฌ์˜จ ๊ฐ’์ด ์ฑ„์›Œ์ง€๋Š” ๊ฒƒ์„ ํ™•์ธํ•œ ์‹œ์ ์œผ๋กœ ์žก์•„๋‘๋ ค ํ•œ๋‹ค.



๐Ÿค” Understanding

์ด๋ฒˆ ์ผ์—์„œ ๋‚จ์€ ๊ฒƒ์€ ์„ธ ๊ฐ€์ง€๋‹ค.

  • ์šฐํšŒ์™€ ์ œ๋ณด๋Š” ๊ฐ™์ด ๋ฌถ์ง€ ์•Š๋Š” ํŽธ์ด ๋‚ซ๋‹ค. ์šฐํšŒ๋ฅผ ๋จผ์ € ๋๋‚ด๋ฉด ์ œ๋ณด๊ฐ€ ๊ธ‰ํ•ด์ง€์ง€ ์•Š๊ณ , ๊ทธ๋งŒํผ ์žฌํ˜„์„ ๋‹ค๋“ฌ์„ ์—ฌ์œ ๊ฐ€ ์ƒ๊ธด๋‹ค. ๋ฐ˜๋Œ€๋กœ ์ œ๋ณด๊ฐ€ ํ•ด๊ฒฐ๋˜๊ธฐ๋ฅผ ๊ธฐ๋‹ค๋ฆฌ๋ฉฐ ๋ฐฐํฌ๋ฅผ ๋ฏธ๋ค˜๋‹ค๋ฉด ๋‘˜ ๋‹ค ๋Šฆ์–ด์กŒ์„ ๊ฒƒ์ด๋‹ค.
  • ์žฌํ˜„์€ ์˜ฌ๋ฆฌ๋Š” ์ชฝ์—์„œ ์ตœ๋Œ€ํ•œ ๋๋‚ด๋‘๋Š” ๊ฒŒ ๋‚ซ๋‹ค. ํ”„๋กœ์ ํŠธ๊ฐ€ ์žฌํ˜„ ๋ฒ ์ด์Šค๋ฅผ ์ œ๊ณตํ•œ๋‹ค๋ฉด ๊ทธ๊ฒƒ์„ fork ํ•˜๋Š” ๊ฒƒ์ด ๋จผ์ €๋‹ค. ์ด์‹ํ•  ๋•Œ ํ•„์š”ํ•œ ์†์งˆ์ด ์ด๋ฏธ ๋๋‚˜ ์žˆ๊ณ , ๋‚ด ์ปค๋ฐ‹ ํ•˜๋‚˜์— ์žฌํ˜„ ์กฐ๊ฑด์ด ๋‹ค ๋‹ด๊ธด๋‹ค. ์—ฌ๊ธฐ์— ํ†ต๊ณผํ•˜๋Š” ๊ฒฝ๋กœ๊นŒ์ง€ ํ•จ๊ป˜ ๋„ฃ์œผ๋ฉด ์„ค์ • ๋ฌธ์ œ๊ฐ€ ์•„๋‹ˆ๋ƒ๋Š” ๋˜๋ฌผ์Œ์ด ๋‚˜์˜ค์ง€ ์•Š๋Š”๋‹ค.
  • ๊ธฐ์—ฌ์˜ ๋‹จ์œ„๊ฐ€ ๊ผญ PR ์€ ์•„๋‹ˆ๋‹ค. ์ด๋ฒˆ์— ๊ณ ์นœ ์‚ฌ๋žŒ์€ ๋‚ด๊ฐ€ ์•„๋‹ˆ์ง€๋งŒ, ๊ณ ์น  ์ˆ˜ ์žˆ๋Š” ํ˜•ํƒœ๋กœ ๋ฌธ์ œ๋ฅผ ์˜ฎ๊ฒจ๋†“๋Š” ์ผ์—๋„ ๋ชซ์ด ์žˆ์—ˆ๋‹ค๊ณ  ์ƒ๊ฐํ•œ๋‹ค. ์ฝ”๋“œ๋ฅผ ์“ธ ์‹œ๊ฐ„์ด ์—†์–ด์„œ ์ œ๋ณด๋ฅผ ๋ฏธ๋ฃจ๋Š” ๊ฒƒ๋ณด๋‹ค๋Š”, ์žฌํ˜„์„ ์ž˜ ๋งŒ๋“ค์–ด ๋„˜๊ธฐ๋Š” ํŽธ์ด ์‹ค์ œ๋กœ ๋” ๋นจ๋ฆฌ ๊ณ ์ณ์ง„๋‹ค.


์ฐธ๊ณ  ์ž๋ฃŒ

Previous
์กฐ์šฉํžˆ ๋น„์–ด๋ฒ„๋ฆฐ ๊ฐ’ ํ•˜๋‚˜์—์„œ ์‹œ์ž‘ํ•œ ORM ๋ฉ”์ด์ € ์—…๊ทธ๋ ˆ์ด๋“œ ๊ฒ€์ฆ ์ „๋žต
๐Ÿ“šBackend
2026.09.18