DevLog ๐Ÿ˜ถ

[JPA] @GeneratedType - ํ‚ค ์ƒ์„ฑ ์ „๋žต ์•Œ์•„๋ณด๊ธฐ ๋ณธ๋ฌธ

Back-end/JPA

[JPA] @GeneratedType - ํ‚ค ์ƒ์„ฑ ์ „๋žต ์•Œ์•„๋ณด๊ธฐ

dolmeng2 2023. 7. 7. 17:16

๐ŸŒฑ JPA ๊ธฐ๋ณธ ํ‚ค ์ƒ์„ฑ ์ „๋žต 

JPA์—์„œ ์ œ๊ณตํ•˜๋Š” ๊ธฐ๋ณธ ํ‚ค ์ƒ์„ฑ ์ „๋žต์€ ํฌ๊ฒŒ 5๊ฐ€์ง€๋กœ ๋‚˜๋ˆ„์–ด์ง„๋‹ค.
- TABLE, SEQUENCE, IDENTITY, UUID, AUTO

๊ฐ ์ „๋žต์— ๋Œ€ํ•ด์„œ ํ•˜๋‚˜์”ฉ ์•Œ์•„๋ณด๋„๋ก ํ•˜์ž.


 

๐ŸŒฑ TABLE

๐Ÿ’ก Indicates that the persistence provider must assign primary keys for the entity using an underlying database table to ensure uniqueness.

- ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ํ…Œ์ด๋ธ”์„ ์‚ฌ์šฉํ•˜์—ฌ ์—”ํ‹ฐํ‹ฐ์— ๊ธฐ๋ณธ ํ‚ค๋ฅผ ํ• ๋‹นํ•ด์•ผ ํ•œ๋‹ค.

 


๐Ÿ’ฌ ์—”ํ‹ฐํ‹ฐ ์„ค์ •

@Entity
class User(
    @Id @GeneratedValue(strategy = GenerationType.TABLE)
    val id: Long = 0L
)

- ๊ฐ€์žฅ ๊ฐ„๋‹จํ•˜๊ฒŒ ์„ค์ •ํ•˜๊ธฐ ์œ„ํ•ด์„œ User ์—”ํ‹ฐํ‹ฐ์— ์•„์ด๋””์— ๋Œ€ํ•œ ํ•„๋“œ๋งŒ ์„ค์ •ํ•ด๋‘์—ˆ๋‹ค.

 

 

๐Ÿ’ฌ h2 database

h2์—์„œ๋Š” ๋จผ์ € user ํ…Œ์ด๋ธ”๊ณผ ์‹œํ€€์Šค๋ฅผ ๊ด€๋ฆฌํ•˜๊ธฐ ์œ„ํ•œ hibernate_sequences ํ…Œ์ด๋ธ”์„ ๋งŒ๋“ ๋‹ค.

์ด๋•Œ ๋‚ด๋ถ€์ ์œผ๋กœ ์‹œํ€€์Šค ๊ฐ’ ์ž์ฒด๋ฅผ ๊ด€๋ฆฌํ•˜๊ธฐ ์œ„ํ•œ next_val๊ณผ ์‹œํ€€์Šค ์ด๋ฆ„ ํ•„๋“œ์ธ sequence_name์„ ๋งŒ๋“ค๋ฉฐ, ์ƒ์„ฑํ•˜๋Š” ํ…Œ์ด๋ธ” ๊ฐ๊ฐ์— ๋Œ€ํ•ด ์‹œํ€€์Šค๋ฅผ ๊ด€๋ฆฌํ•˜๊ฒŒ ๋œ๋‹ค.

์ดํ›„, ๊ฐ€์žฅ ์ฒ˜์Œ ์‹œํ€€์Šค ๊ฐ’์„ ์ดˆ๊ธฐํ™”ํ•˜๊ธฐ ์œ„ํ•ด์„œ insert๋ฅผ ์ง„ํ–‰ํ•˜๋ฉฐ, 0์œผ๋กœ ์ดˆ๊ธฐํ™”๋ฅผ ํ•ด๋‘์—ˆ๋‹ค.



๐Ÿ’ฌ mysql

mysql ์—ญ์‹œ ๋งˆ์ฐฌ๊ฐ€์ง€๋กœ user์™€ ์‹œํ€€์Šค๋ฅผ ๊ด€๋ฆฌํ•˜๊ธฐ ์œ„ํ•œ ํ…Œ์ด๋ธ”์„ ์ถ”๊ฐ€ํ•œ๋‹ค.

innoDB ์Šคํ† ๋ฆฌ์ง€ ์—”์ง„์„ ์‚ฌ์šฉํ•œ๋‹ค๋Š” ์  ๋นผ๊ณ ๋Š” ๋™์ผํ•˜๋‹ค.

 

 

๐Ÿ’ฌ postgresql

postgresql์—์„œ๋„ ์™„์ „ํžˆ ๋™์ผํ•˜๊ฒŒ ๋™์ž‘ํ•˜๊ธฐ ๋•Œ๋ฌธ์— ์ƒ๋žตํ•˜๊ฒ ๋‹ค.

 

 

๐Ÿ’ฌ insert ์‹œ ๋™์ž‘ ๊ณผ์ •

๊ธฐ๋ณธ์ ์œผ๋กœ select๋ฅผ ํ†ตํ•ด์„œ ํ˜„์žฌ ํ…Œ์ด๋ธ”์— ์ €์žฅ๋˜์–ด ์žˆ๋Š” ์‹œํ€€์Šค ๊ฐ’์„ ๊ฐ€์ ธ์˜จ๋‹ค. 

์ด๋•Œ, select for update ๊ตฌ๋ฌธ์„ ํ™œ์šฉํ•˜์—ฌ ๋ฝ์„ ๊ฑธ๊ณ  ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ์™ธ๋ถ€์—์„œ ํ•ด๋‹น ํ…Œ์ด๋ธ”์— ๊ฐ’์„ ์‚ฝ์ž…ํ•  ์ˆ˜๊ฐ€ ์—†์–ด ๋ฐ์ดํ„ฐ์˜ ์ผ๊ด€์„ฑ์€ ๋งŒ์กฑ๋œ๋‹ค. ์ดํ›„, ๊ฐ€์ ธ์˜จ ๊ฐ’์„ ๋ฐ”ํƒ•์œผ๋กœ ์‹œํ€€์Šค ๊ฐ’์„ update ํ•ด์ฃผ๊ณ , ์ตœ์ข…์ ์œผ๋กœ user ์—”ํ‹ฐํ‹ฐ์— ๋Œ€ํ•ด insert๋ฅผ ์ง„ํ–‰ํ•œ๋‹ค.

 

์œ„์˜ ์ƒํ™ฉ์—์„œ๋Š” ๋””ํดํŠธ๋กœ 0์ด ์ €์žฅ๋˜์–ด ์žˆ๊ณ , update ์‹œ 1์„ ์ถ”๊ฐ€ํ•˜์—ฌ 0 + 1 = 1์˜ ๊ฐ’์„ ๊ฐ€์ง€๊ณ , insert ์‹œ ์—…๋ฐ์ดํŠธ๋œ ๊ฐ’์„ ํ†ตํ•ด์„œ id๋ฅผ ํ• ๋‹นํ•œ ์ƒํ™ฉ์ด๋ผ๊ณ  ๋ณผ ์ˆ˜ ์žˆ๋‹ค.

 

๐Ÿ’ฌ @TableGenerator

@Entity
class User(
    @Id @GeneratedValue(strategy = GenerationType.TABLE, generator = "user_seq_generator")
    @TableGenerator(name = "user_seq_generator", table="user_sequence",
        pkColumnName = "name", pkColumnValue = "user_col", allocationSize = 50)
    val id: Long = 0L
)

ํ…Œ์ด๋ธ” ์ „๋žต์˜ ๊ฒฝ์šฐ @TableGenerator ์–ด๋…ธํ…Œ์ด์…˜๊ณผ ํ•จ๊ป˜ ์‚ฌ์šฉํ•˜๋ฉด ์‹œํ€€์Šค ํ…Œ์ด๋ธ”์— ๋Œ€ํ•œ ์ •๋ณด๋ฅผ ์ปค์Šคํ…€ํ•  ์ˆ˜ ์žˆ๋‹ค.

- name: ์ƒ์„ฑํ•˜๋Š” ์ œ๋„ˆ๋ ˆ์ดํ„ฐ์˜ ์ด๋ฆ„ (@GeneratedValue์˜ ์ธ์ž๋กœ ์ œ๋„ˆ๋ ˆ์ดํ„ฐ๋ฅผ ์ฐธ์กฐํ•  ๋•Œ ์ฐธ์กฐํ•˜๋Š” ์ด๋ฆ„์ด๋‹ค.)
- table: ์ƒ์„ฑํ•˜๋Š” ์ œ๋„ˆ๋ ˆ์ดํ„ฐ ํ…Œ์ด๋ธ”์˜ ์ด๋ฆ„
- pkColumnName: ์ œ๋„ˆ๋ ˆ์ดํ„ฐ ํ…Œ์ด๋ธ”์—์„œ ์ง€์ •ํ•  ์‹œํ€€์Šค ์ด๋ฆ„ ํ•„๋“œ๋ช…
- pkColumnValue: ์‹œํ€€์Šค ์ด๋ฆ„ ํ•„๋“œ์— ๋Œ€ํ•ด์„œ ํ•ด๋‹น ํ…Œ์ด๋ธ”์„ ์–ด๋–ค ์ด๋ฆ„์œผ๋กœ ๊ด€๋ฆฌํ• ์ง€ ์ง€์ •
- allocationSize: ์‚ฌ์ „์— ์ •์˜ํ•œ ์‹œํ€€์Šค ์‚ฌ์ด์ฆˆ. DB์—์„œ๋Š” ํ• ๋‹นํ•œ ์‚ฌ์ด์ฆˆ๋งŒํผ ๋จผ์ € ์ˆ˜๋ฅผ ์ฆ๊ฐ€์‹œ์ผœ๋‘๊ณ , ํŠธ๋žœ์žญ์…˜์ด ๋๋‚  ๋•Œ๋งˆ๋‹ค ์‚ฌ์ด์ฆˆ๋งŒํผ ์ถ”๊ฐ€ํ•œ๋‹ค. (๊ธฐ๋ณธ๊ฐ’์ด 50์ด๊ธฐ ๋•Œ๋ฌธ์— ํ•„์š”ํ•˜๋‹ค๋ฉด 1๋กœ ์„ค์ •!)

 

์œ„์˜ ์ •๋ณด ์™ธ์—๋„ ๋‹ค์–‘ํ•œ ์„ค์ •๊ฐ’๋“ค์„ ์„ธํŒ…ํ•  ์ˆ˜ ์žˆ๋‹ค.

 

@Test
@Transactional
fun test() {
    userRepository.save(User())
}

์‹ค์ œ๋กœ, allocationSize์— ๋Œ€ํ•ด ํ…Œ์ŠคํŠธ๋ฅผ ํ•˜๊ธฐ ์œ„ํ•ด ์œ„์™€ ๊ฐ™์ด ์‚ฌ์šฉ์ž ์ •๋ณด๋ฅผ ์ €์žฅํ•ด๋ณด์ž.

์šฐ์„ , ์•ž์„œ ๋ดค๋˜ ๊ฒƒ์ฒ˜๋Ÿผ ์‹œํ€€์Šค ์ •๋ณด๋ฅผ select ํ›„ ํ•ด๋‹น ๊ฐ’์„ update ํ•œ ๊ฒƒ์„ ๋ณผ ์ˆ˜ ์žˆ๋‹ค.

๊ทธ๋ฆฌ๊ณ  sequence ์ •๋ณด๋ฅผ ํ™•์ธํ•ด๋ณด๋ฉด, user ํ•˜๋‚˜๋งŒ ์ €์žฅํ–ˆ์Œ์—๋„ ํ• ๋‹นํ•œ ํฌ๊ธฐ(50)๋งŒํผ ๊ฐ’์ด ์ถ”๊ฐ€๋œ ๊ฒƒ์„ ๋ณผ ์ˆ˜ ์žˆ๋‹ค.

 

๋งŒ์•ฝ, ๋‹ค์‹œ ํ•œ ๋ฒˆ ํ…Œ์ŠคํŠธ ์ฝ”๋“œ๋ฅผ ์‹คํ–‰ํ•˜๊ฒŒ ๋œ๋‹ค๋ฉด ๋‹ค์Œ sequence๋Š” ์–ด๋–ป๊ฒŒ ๋ ๊นŒ? (ddl๋Š” update๋กœ ์„ค์ •)

์ด๋•Œ๋Š” db์— next_val์ด 100์œผ๋กœ ์ €์žฅ์ด ๋˜์–ด ์žˆ๋‹ค. (๊ธฐ์กด next_val ๊ฐ’ 50 + allocationSize 50 = 100)

@Test
@Transactional
fun test() {
    // ํ•œ ๋ฒˆ ๋” ์‹คํ–‰ํ–ˆ์„ ๋•Œ์˜ ๊ฒฐ๊ณผ
    val user = userRepository.save(User())
    assertThat(user.id).isEqualTo(2)
}

ํ•˜์ง€๋งŒ, user์˜ pk ๊ฐ’์€ 2๋กœ ๋‚˜์˜ค๋Š” ๊ฒƒ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋‹ค. ์ด๋Š” ๋‚ด๋ถ€์ ์œผ๋กœ ๋ฐ›์•„์˜จ next_val์˜ ๊ฐ’๊ณผ allocationSize ๊ฐ’์„ ๋ฐ”ํƒ•์œผ๋กœ pk๋ฅผ ๊ณ„์‚ฐํ•œ ๊ฐ’์ด๋‹ค. ๋ ˆ์ฝ”๋“œ 1๊ฐœ๋ฅผ ์‚ฝ์ž…ํ•  ๋•Œ, ์ฒ˜์Œ select ์‹œ ์–ป์–ด์˜จ (next_val - allocation_size) + 1์œผ๋กœ ํ• ๋‹น๋œ๋‹ค.

 



๐ŸŒฑ SEQUENCE

๐Ÿ’ก Indicates that the persistence provider must assign primary keys for the entity using a database sequence.

๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์—์„œ ์ œ๊ณตํ•˜๋Š” ์‹œํ€€์Šค๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์—”ํ‹ฐํ‹ฐ์˜ ๊ธฐ๋ณธ ํ‚ค๋ฅผ ํ• ๋‹นํ•ด์•ผ ํ•œ๋‹ค.

์ด๋•Œ, ์‹œํ€€์Šค๋ฅผ ์ง€์›ํ•˜์ง€ ์•Š๋Š” DB๋ผ๋ฉด ํ…Œ์ด๋ธ” ์ „๋žต์„ ์‚ฌ์šฉํ•œ๋‹ค.

 

 

๐Ÿ’ฌ ์—”ํ‹ฐํ‹ฐ ์„ค์ •

@Entity
class User(
    @Id @GeneratedValue(strategy = GenerationType.SEQUENCE)
    val id: Long = 0L
)



๐Ÿ’ฌ h2 database

h2์˜ ๊ฒฝ์šฐ sequence๋ฅผ ์ง€์›ํ•˜๊ธฐ ๋•Œ๋ฌธ์— ‘create sequence’๋ผ๋Š” ๊ฒƒ์„ ํ†ตํ•ด์„œ sequence ๊ด€๋ฆฌํ•œ๋‹ค.
์ด๋•Œ, ๋””ํดํŠธ๋กœ ์‹œํ€€์Šค ๊ฐ’์€ 1๋ถ€ํ„ฐ ์‹œ์ž‘ํ•˜์—ฌ 50์”ฉ ์ฆ๊ฐ€ํ•œ๋‹ค. ์ฆ‰, ํ•˜๋‚˜์˜ ํŠธ๋žœ์žญ์…˜์ด ๋๋‚˜๋ฉด 50๊ฐœ ์ดํ•˜๋ฅผ ์‚ฝ์ž…ํ•˜๋”๋ผ๋„ 50์”ฉ ์‹œํ€€์Šค ๊ฐ’์ด ์ฆ๊ฐ€ํ•˜๊ธฐ ๋•Œ๋ฌธ์— ์ค‘๊ฐ„์ค‘๊ฐ„ ๋น„์–ด์žˆ๋Š” PK ๊ฐ’์„ ๊ฐ€์งˆ ์ˆ˜ ์žˆ๋‹ค๋Š” ๊ฒƒ์ด ํŠน์ง•์ด๋‹ค.

 


๐Ÿ’ฌ mysql

โญ๏ธ ๊ทธ๋Ÿฌ๋‚˜, mysql์—์„œ๋Š” sequence๋ฅผ ์ง€์›ํ•˜์ง€ ์•Š๊ธฐ ๋•Œ๋ฌธ์— ํ…Œ์ด๋ธ” ์ „๋žต์ฒ˜๋Ÿผ user_seq๋ผ๋Š” ํ…Œ์ด๋ธ”์ด ์ƒ์„ฑ๋œ๋‹ค.
์ด๋•Œ, ์‹œํ€€์Šค ํ…Œ์ด๋ธ”์— ๋Œ€ํ•œ ๋„ค์ด๋ฐ์€ ์—”ํ‹ฐํ‹ฐ๋ช… + _seq์™€ ๊ฐ™์€ ํ˜•ํƒœ๋กœ ๋™์ž‘ํ•œ๋‹ค.

 

 

๐Ÿ’ฌ postgresql

h2์™€ ๋งˆ์ฐฌ๊ฐ€์ง€๋กœ postgresql ์—ญ์‹œ sequence๋ฅผ ์ง€์›ํ•˜๊ธฐ ๋•Œ๋ฌธ์— create sequence๋ฅผ ํ†ตํ•ด์„œ ์‹œํ€€์Šค๋ฅผ ์ƒ์„ฑํ•œ๋‹ค.

 


๐Ÿ’ฌ insert ์‹œ ๋™์ž‘ ๊ณผ์ •

๋จผ์ €, ์‹œํ€€์Šค๋กœ๋ถ€ํ„ฐ ๋‹ค์Œ ๊ฐ’์„ ๋ฐ›์•„์˜ค๋Š” select ์ฟผ๋ฆฌ๊ฐ€ ๋ฐœ์ƒํ•œ๋‹ค. ("next value for" = 1์ด๋ผ๋Š” ๊ฐ’์„ ๋ฐ›์•„์˜จ๋‹ค.)

์ด์ „์˜ TABLE ์ „๋žต๊ณผ ๋‹ค๋ฅด๊ฒŒ '๊ทธ ๋‹ค์Œ insert ์‹œ ์‚ฌ์šฉํ•  ์‹œํ€€์Šค ๊ฐ’'์„ ์ €์žฅํ•˜๊ธฐ ๋•Œ๋ฌธ์— ์‹œํ€€์Šค์— ๋Œ€ํ•œ ๋ณ„๋„์˜ update๋ฅผ ์ฟผ๋ฆฌ๋กœ ๊ด€๋ฆฌํ•˜๋Š” ๊ฒƒ์ด ์•„๋‹Œ ๋‚ด๋ถ€์ ์œผ๋กœ ๊ด€๋ฆฌ๋œ๋‹ค๊ณ  ์ถ”์ธก๋œ๋‹ค. (๋ฌผ๋ก  MySQL์ด๋ผ๋ฉด ํ…Œ์ด๋ธ” ์ „๋žต์ด๊ธฐ ๋•Œ๋ฌธ์— update ์ฟผ๋ฆฌ ๋ฐœ์ƒ)

๋˜ํ•œ, ์ถ”ํ›„ ๋‚˜์˜ฌ IDENTITY ์ „๋žต๊ณผ ๋‹ค๋ฅด๊ฒŒ persist ์‹œ insert๋ฅผ ํ•˜์ง€ ์•Š์•„๋„ ๋ผ์„œ ํŠธ๋žœ์žญ์…˜ ์ปค๋ฐ‹ ์‹œ insert๊ฐ€ ์ด๋ฃจ์–ด์ง„๋‹ค. (์“ฐ๊ธฐ ์ง€์—ฐ ๊ฐ€๋Šฅ) 

 

 

๐Ÿ’ฌ @SequenceGenerator

@Entity
class User(
    @Id @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "user_seq_generator")
    @SequenceGenerator(name = "user_seq_generator", sequenceName = "user_sequence",
        initialValue = 10, allocationSize = 50)
    val id: Long = 0L
)

 

@SequenceGenerator๋ฅผ ํ™œ์šฉํ•˜๋ฉด ์‹œํ€€์Šค์— ๋Œ€ํ•œ ์ •๋ณด๋ฅผ ์„ค์ •ํ•ด์ค„ ์ˆ˜ ์žˆ๋‹ค.
- name: ์ƒ์„ฑํ•˜๋Š” ์ œ๋„ˆ๋ ˆ์ดํ„ฐ์˜ ์ด๋ฆ„ (@GeneratedValue์˜ ์ธ์ž๋กœ ์ œ๋„ˆ๋ ˆ์ดํ„ฐ๋ฅผ ์ฐธ์กฐํ•  ๋•Œ ์ฐธ์กฐํ•˜๋Š” ์ด๋ฆ„์ด๋‹ค.)
- sequenceName: ์ƒ์„ฑํ•˜๋Š” ์‹œํ€€์Šค์˜ ์ด๋ฆ„
- initialValue: ์‹œํ€€์Šค์˜ ์ดˆ๊ธฐ๊ฐ’
- allocationSize: ์‚ฌ์ „์— ์ •์˜ํ•œ ์‹œํ€€์Šค ์‚ฌ์ด์ฆˆ. DB์—์„œ๋Š” ํ• ๋‹นํ•œ ์‚ฌ์ด์ฆˆ๋งŒํผ ๋จผ์ € ์ˆ˜๋ฅผ ์ฆ๊ฐ€์‹œ์ผœ๋‘๊ณ , ํŠธ๋žœ์žญ์…˜์ด ๋๋‚  ๋•Œ๋งˆ๋‹ค ์‚ฌ์ด์ฆˆ๋งŒํผ ์ถ”๊ฐ€ํ•œ๋‹ค.
๋งˆ์ฐฌ๊ฐ€์ง€๋กœ ์œ„์˜ ์ •๋ณด ์™ธ์—๋„ ๋‹ค์–‘ํ•œ ์„ค์ •๊ฐ’๋“ค์„ ์„ธํŒ…ํ•  ์ˆ˜ ์žˆ๋‹ค.

 

ํ‚ค ํ• ๋‹น ์ „๋žต์€ table ๋•Œ์™€ ๋˜‘๊ฐ™์ด (next_val - allocation_size) + 1์™€ ๊ฐ™์ด ์„ค์ •๋œ๋‹ค.

 



๐ŸŒฑ IDENTITY

๐Ÿ’ก Indicates that the persistence provider must assign primary keys for the entity using a database identity column.

- ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์˜ auto-increment ์—ด์„ ์‚ฌ์šฉํ•˜์—ฌ ์—”ํ‹ฐํ‹ฐ์— ๊ธฐ๋ณธ ํ‚ค๋ฅผ ํ• ๋‹นํ•ด์•ผ ํ•œ๋‹ค.
๋ ˆ์ฝ”๋“œ๊ฐ€ ์ƒˆ๋กญ๊ฒŒ ์ถ”๊ฐ€๋  ๋•Œ๋งˆ๋‹ค ์ž๋™์œผ๋กœ ๊ณ ์œ ๊ฐ’์„ ์ƒ์„ฑํ•˜๊ณ  ์ฆ๊ฐ€์‹œํ‚จ๋‹ค.

 


๐Ÿ’ฌ ์—”ํ‹ฐํ‹ฐ ์„ค์ •

@Entity
class User(
    @Id @GeneratedValue(strategy = GenerationType.IDENTITY)
    val id: Long = 0L
)



๐Ÿ’ฌ h2 database

๋ณ„๋„์˜ ์‹œํ€€์Šค ํ…Œ์ด๋ธ”์„ ์ƒ์„ฑํ•˜์ง€ ์•Š๊ณ , pk๋กœ ์‚ฌ์šฉ๋œ ์ปฌ๋Ÿผ์— as identity๋ผ๋Š” ์ด๋ฆ„์ด ๋“ค์–ด๊ฐ„๋‹ค.

 


๐Ÿ’ฌ mysql

h2์™€ ๊ฑฐ์˜ ๋น„์Šทํ•˜์ง€๋งŒ auto_increment๊ฐ€ pk ์ปฌ๋Ÿผ์— ๋ถ™๊ฒŒ ๋œ๋‹ค.

cf. ์ฐธ๊ณ ๋กœ innoDB์—์„œ๋Š” auto_increment๋ฅผ ์œ„ํ•œ ์ž๋™ ์ฆ๊ฐ€ ๋ฝ์ด๋ผ๋Š” ๊ฒƒ์„ ํ†ตํ•ด์„œ ํ•ด๋‹น ๊ฐ’์„ ๊ด€๋ฆฌํ•œ๋‹ค.

 


๐Ÿ’ฌ postgresql

postgresql์˜ ๊ฒฝ์šฐ bigserial์ด๋ผ๋Š” ๊ฐ’์„ ํ†ตํ•ด์„œ ๊ด€๋ฆฌํ•œ๋‹ค.
์ด๋Š” postgresql์—์„œ ์‚ฌ์šฉํ•˜๋Š” ์ž๋™ ์ฆ๊ฐ€ ํƒ€์ž…์œผ๋กœ, ์ปฌ๋Ÿผ์ด ์‚ฝ์ž…๋  ๋•Œ๋งˆ๋‹ค 1์”ฉ ์ฆ๊ฐ€๋œ ๊ฐ’์ด ์ €์žฅ๋œ๋‹ค.

 

 

๐Ÿ’ฌ insert ์‹œ ๋™์ž‘ ๊ณผ์ •

์•ž์„œ ๋ณธ ํ…Œ์ด๋ธ”, ์‹œํ€€์Šค ์ „๋žต๊ณผ ๋‹ค๋ฅด๊ฒŒ select ์ฟผ๋ฆฌ๊ฐ€ ์—†์ด ๋ฐ”๋กœ insert ์ฟผ๋ฆฌ๊ฐ€ ๋ฐœ์ƒํ•œ๋‹ค.

์ด๋•Œ, ()์™€ ๊ฐ™์ด ๋นˆ ๊ฐ’์ด ๋“ค์–ด๊ฐ€๋Š” ๊ฒƒ์„ ๋ณผ ์ˆ˜ ์žˆ๋Š”๋ฐ, ์ด๋Š” ์‚ฝ์ž…ํ•˜๋Š” ์‹œ์ ์—๋Š” id ๊ฐ’์„ ์•Œ ์ˆ˜ ์—†๊ธฐ ๋•Œ๋ฌธ์— ๋นˆ๊ฐ’ (java๋ผ๋ฉด null)์ด ๋“ค์–ด๊ฐ€๋Š” ๊ฒƒ์ด๋‹ค. ์ฆ‰, ์‚ฝ์ž… ์‹œ์ ์˜ id ๊ฐ’์„ ์• ์ดˆ์— ๋ชจ๋ฅด๋‹ˆ๊นŒ ์‚ฝ์ž… ์ „์— select ์ฟผ๋ฆฌ๋ฅผ ๋‚ ๋ฆด ์ˆ˜ ์—†๋Š” ๊ฒƒ์ด๋‹ค.


IDENTITY ์ „๋žต ์‚ฌ์šฉ ์‹œ ํŠธ๋žœ์žญ์…˜ ์ปค๋ฐ‹ ์‹œ์ ์ด ์•„๋‹Œ, persist ์‹œ์ ์— ์ฟผ๋ฆฌ๊ฐ€ ๋ฐœ์ƒํ•˜์—ฌ, ์“ฐ๊ธฐ ์ง€์—ฐ์ด ๋ถˆ๊ฐ€๋Šฅํ•˜๋‹ค.

๊ธฐ๋ณธ์ ์œผ๋กœ JPA์˜ ์˜์†์„ฑ ์ปจํ…์ŠคํŠธ์—์„œ ๊ฐ์ฒด๋ฅผ ๊ด€๋ฆฌํ•˜๊ธฐ ์œ„ํ•ด์„œ๋Š” @Id ์†์„ฑ์ด ๊ผญ ํ•„์š”ํ•œ๋ฐ auto_increment์˜ ๊ฒฝ์šฐ DB์— ์ง์ ‘ ๋ ˆ์ฝ”๋“œ๋ฅผ insert๋ฅผ ํ•œ ๋’ค์— ID ๊ฐ’์„ ์•Œ ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ์— persist() ์‹œ์ ์— insert๋ฅผ ์ง„ํ–‰ํ•˜์—ฌ ์‹๋ณ„์ž๋ฅผ ๋ฏธ๋ฆฌ ์•Œ์•„๋‘”๋‹ค. ์ดํ›„, ์•Œ์•„๋ณธ ๊ฐ’์„ ์˜์†์„ฑ ์ปจํ…์ŠคํŠธ์˜ 1์ฐจ ์บ์‹œ ๋‚ด๋ถ€์— ์ €์žฅํ•œ๋‹ค.



๐Ÿ’ฌ IDENTITY with generator

๋‘ ์†์„ฑ์„ ๊ฐ™์ด ์“ฐ๋ฉด ์–ด๋–ป๊ฒŒ ๋™์ž‘ํ• ์ง€ ๊ถ๊ธˆํ•ด์„œ ์‹คํ—˜ํ•ด๋ณด์•˜๋‹ค.

@Entity
class User(
    @Id @GeneratedValue(strategy = GenerationType.IDENTITY, generator = "user_seq_generator")
    @SequenceGenerator(name = "user_seq_generator", sequenceName = "user_sequence",
        initialValue = 10, allocationSize = 50)
    val id: Long = 0L
)

ํ™•์ธ ๊ฒฐ๊ณผ, ์‹œํ€€์Šค ์˜ต์…˜์ด ๋” ์šฐ์„ ์œผ๋กœ ์ ์šฉ๋˜๋Š” ๊ฒƒ์„ ๋ณผ ์ˆ˜ ์žˆ๋‹ค.

์ฐธ๊ณ ๋กœ, ํ…Œ์ด๋ธ” ์ œ๋„ˆ๋ ˆ์ดํ„ฐ๋ฅผ ์‚ฌ์šฉํ•˜๋”๋ผ๋„ ๋งˆ์ฐฌ๊ฐ€์ง€๋กœ ์šฐ์„  ์ ์šฉ๋œ๋‹ค.

 



๐ŸŒฑ AUTO

๐Ÿ’ก Indicates that the persistence provider should pick an appropriate strategy for the particular database.
The AUTO generation strategy may expect a database resource to exist, or it may attempt to create one.
A vendor may provide documentation on how to create such resources in the event that it does not support schema generation or cannot create the schema resource at runtime.

ํŠน์ • ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์— ๋”ฐ๋ฅธ ์ ์ ˆํ•œ ์ „๋žต์„ ์„ ํƒํ•˜๋ฉฐ, ๋ฒค๋” ์‚ฌ์— ๋”ฐ๋ผ์„œ ์ž๋™์œผ๋กœ ๊ฒฐ์ •๋œ๋‹ค.

 


๐Ÿ’ฌ ์—”ํ‹ฐํ‹ฐ ์„ค์ •

@Entity
class User(
    @Id @GeneratedValue(strategy = GenerationType.AUTO)
    val id: Long = 0L
)



๐Ÿ’ฌ h2 database

h2์˜ ๊ฒฝ์šฐ ์‹œํ€€์Šค๋ฅผ ์ง€์›ํ•˜๊ธฐ ๋•Œ๋ฌธ์— ์‹œํ€€์Šค ์ „๋žต์„ ์ž๋™์œผ๋กœ ์ฑ„ํƒํ•œ๋‹ค.

 

 

๐Ÿ’ฌ mysql

์‹œํ€€์Šค ์ „๋žต์„ ์ง€์›ํ•˜์ง€ ์•Š๋Š” mysql์˜ ๊ฒฝ์šฐ ํ…Œ์ด๋ธ” ์ „๋žต์„ ์‚ฌ์šฉํ•œ๋‹ค.

 


๐Ÿ’ฌ postgresql

h2์™€ ๋งˆ์ฐฌ๊ฐ€์ง€๋กœ ์‹œํ€€์Šค ์ „๋žต์„ ์‚ฌ์šฉํ•œ๋‹ค.

 


๐Ÿ’ฌ SEQUENCE vs AUTO

์—ฌ๊ธฐ๊นŒ์ง€๋งŒ ๋ดค๋‹ค๋ฉด ์‹œํ€€์Šค ์ „๋žต์ด๋‚˜ auto๋‚˜ ๋ณ„๋‹ค๋ฅธ ๊ฒŒ ์—†๋‹ค๊ณ  ์ƒ๊ฐ์ด ๋“ค ๊ฒƒ์ด๋‹ค.
ํ•˜์ง€๋งŒ, pk๊ฐ€ uuid์ธ ‘์—”ํ‹ฐํ‹ฐ๋ฅผ ์ €์žฅํ•  ๋•Œ’ ์‹œํ€€์Šค ์ „๋žต์˜ ๊ฒฝ์šฐ ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ•˜๊ณ , auto์˜ ๊ฒฝ์šฐ ์ •์ƒ์ ์œผ๋กœ ๋™์ž‘ํ•œ๋‹ค.

์ด๋•Œ, ๋‹จ์ˆœํžˆ ํ…Œ์ด๋ธ” ์ƒ์„ฑ ์ž์ฒด๋Š” ์ •์ƒ์ ์œผ๋กœ ๋™์ž‘ํ•œ๋‹ค.

 

 

sequence

@Entity
class User(
    @Id @GeneratedValue(strategy = GenerationType.SEQUENCE)
    val id: UUID = UUID.randomUUID()
)

h2๋กœ ํ…Œ์ŠคํŠธ๋ฅผ ์ง„ํ–‰ํ–ˆ๊ธฐ ๋•Œ๋ฌธ์— ์‹œํ€€์Šค ํ…Œ์ด๋ธ”์„ ์ƒ์„ฑํ•˜๋Š” ๊ฒƒ์„ ๋ณผ ์ˆ˜ ์žˆ๋‹ค.

์ด๋•Œ, user ํ…Œ์ด๋ธ”์˜ id๊ฐ€ uuid๋กœ ์„ค์ •๋œ ๊ฒƒ์„ ๋ณผ ์ˆ˜ ์žˆ๋‹ค.

 

userRepository.save(User())

๊ธฐ๋ณธ์ ์œผ๋กœ User ๊ฐ์ฒด์˜ id์— ๊ธฐ๋ณธ๊ฐ’์„ ์ •์˜ํ•˜์˜€๊ธฐ ๋•Œ๋ฌธ์— select ์ฟผ๋ฆฌ๋ฅผ ํ†ตํ•ด์„œ ์ด๋ฏธ ๊ฐ์ฒด๊ฐ€ ์กด์žฌํ•˜๋Š”์ง€ ํ™•์ธํ•œ ๋‹ค์Œ, ์กด์žฌํ•˜์ง€ ์•Š์œผ๋ฉด user_seq์˜ ์‹œํ€€์Šค ๊ฐ’์œผ๋กœ๋ถ€ํ„ฐ ๋‹ค์Œ ๊ฐ’์„ ๊ฐ€์ ธ์˜จ๋‹ค.

 

Unknown integral data type for ids: java.util.UUID

ํ•˜์ง€๋งŒ, ์ดํ›„ UUID ํƒ€์ž…์œผ๋กœ๋Š” save๊ฐ€ ๋˜์ง€ ์•Š๋Š”๋‹ค๋Š” ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ•œ๋‹ค.
์ด๋Š”, ์ดˆ๊ธฐ sequence ์ •์˜๋ฅผ ๋ณด๋ฉด 1๋ถ€ํ„ฐ ์‹œ์ž‘ํ•˜์—ฌ 50์”ฉ ์ฆ๊ฐ€ํ•˜๋Š” ๋””ํดํŠธ ์„ค์ •์„ ๊ฐ€์ง€๊ณ  ์žˆ์ง€๋งŒ, pk ๊ฐ’์ด uuid๋กœ ๋˜์–ด ์žˆ๋‹ค ๋ณด๋‹ˆ uuid์— ๋Œ€ํ•ด ์ฆ๊ฐ€ ์—ฐ์‚ฐ์„ ํ•  ์ˆ˜ ์—†์–ด ๋ฐ์ดํ„ฐ ํƒ€์ž…์— ๋Œ€ํ•œ ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ•œ๋‹ค.

 


auto

@Entity
class User(
    @Id @GeneratedValue(strategy = GenerationType.AUTO)
    val id: UUID = UUID.randomUUID()
)

์‹œํ€€์Šค๋ฅผ ์ง€์›ํ•˜๋Š” h2์ž„์—๋„, ์‹œํ€€์Šค๋ฅผ ์ƒ์„ฑํ•˜์ง€ ์•Š๊ณ  ๋‹จ์ˆœํžˆ pk๊ฐ€ UUID์ธ user ํ…Œ์ด๋ธ”์„ ์ƒ์„ฑํ•˜๋Š” ๊ฒƒ์„ ๋ณผ ์ˆ˜ ์žˆ๋‹ค.

 

userRepository.save(User())

์šฐ์„  ์•„์ด๋”” ๊ฐ’์— ๋Œ€ํ•ด์„œ UUID.randomUUID()๋ฅผ ํ™œ์šฉํ•˜์—ฌ ๊ธฐ๋ณธ๊ฐ’์„ ์„ค์ •ํ•˜๊ฒŒ ๋˜๋ฉด, ์ด๋ฏธ ์กด์žฌํ•˜๋Š” ๋ ˆ์ฝ”๋“œ์ธ์ง€ ํ™•์ธํ•˜๊ธฐ ์œ„ํ•ด ์ €์žฅ ์ „์— select ์ฟผ๋ฆฌ๊ฐ€ ๋ฐœ์ƒํ•˜๊ณ  ์ดํ›„ insert ์ฟผ๋ฆฌ๊ฐ€ ๋‚ ๋ผ๊ฐ„๋‹ค. ์ด๋•Œ, ๋ ˆ์ฝ”๋“œ ์‚ฝ์ž… ์‹œ ํ•ด๋‹น PK ๊ฐ’์„ ์ฆ๊ฐ€์‹œํ‚ค๋ฉด์„œ ๊ด€๋ฆฌํ•  ํ•„์š”๊ฐ€ ์—†๊ธฐ ๋•Œ๋ฌธ์— ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ•˜์ง€ ์•Š๊ณ  ์ž˜ ์ง€์ •๋˜๋Š” ๊ฒƒ์„ ๋ณผ ์ˆ˜ ์žˆ๋‹ค.

 


identity (๋ฒˆ์™ธ)

@Entity
class User(
    @Id @GeneratedValue(strategy = GenerationType.IDENTITY)
    val id: Long = 0L
)

์ฐธ๊ณ ๋กœ, identity๋กœ ์„ค์ •ํ–ˆ์„ ๋•Œ๋Š” save๊ฐ€ ์•„๋‹Œ ํ…Œ์ด๋ธ”์„ ์ƒ์„ฑํ•˜๋Š” ์‹œ์ ๋ถ€ํ„ฐ ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ•œ๋‹ค.

uuid ์ž์ฒด๋ฅผ ์ž๋™ ์ฆ๊ฐ€๊ฐ’์œผ๋กœ ๊ด€๋ฆฌํ•  ์ˆ˜ ์—†๊ธฐ ๋•Œ๋ฌธ์— ๋ฐœ์ƒํ•˜๋Š” ์˜ค๋ฅ˜์ด๋‹ค.

 

โญ๏ธ ๊ฒฐ๊ณผ์ ์œผ๋กœ ์‹๋ณ„์ž ํƒ€์ž…์ด UUID๋ฉด UUID๋ฅผ ์‹๋ณ„์ž๋กœ ์‚ฌ์šฉํ•˜๊ณ , ์ˆซ์ž๋ฉด์„œ ์‹œํ€€์Šค๋ฅผ ์ง€์›ํ•˜๋ฉด ์‹œํ€€์Šค๋กœ, ์•„๋‹ˆ๋ฉด ํ…Œ์ด๋ธ”๋กœ ์‚ฌ์šฉํ•œ๋‹ค๊ณ  ์ƒ๊ฐํ•˜๋ฉด ๋œ๋‹ค.

 



๐ŸŒฑ UUID

๐Ÿ’ก Indicates that the persistence provider must assign primary keys for the entity by generating an RFC 4122 Univerally Unique IDentifier.

- RFC 4122 Universally Unique Identifier๋ฅผ ํ†ตํ•ด์„œ ์—”ํ‹ฐํ‹ฐ์˜ ๊ธฐ๋ณธ ํ‚ค๋ฅผ ํ• ๋‹นํ•  ์ˆ˜ ์žˆ๋‹ค.
PK ํ•„๋“œ ์ž์ฒด๋ฅผ UUID๋กœ ์„ค์ •ํ•˜๊ณ , AUTO ์ „๋žต์„ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ๊ณผ ๋™์ผํ•˜๊ฒŒ ๋™์ž‘ํ•œ๋‹ค.

 


๐Ÿ’ฌ ์—”ํ‹ฐํ‹ฐ ์„ค์ •

@Entity
class User(
    @Id @GeneratedValue(strategy = GenerationType.UUID)
    val id: Long = 0L
)

 

 

๐Ÿ’ฌ h2 database

id ๊ฐ’์˜ ํƒ€์ž…์œผ๋กœ uuid๊ฐ€ ์„ค์ •๋˜๋Š” ๊ฒƒ์„ ๋ณผ ์ˆ˜ ์žˆ๋‹ค. ์ด๋•Œ ๋ณ„๋„์˜ ์‹œํ€€์Šค๊ฐ€ ์žˆ๋‹ค๋“ ์ง€, ์ž๋™ ์ฆ๊ฐ€ ์ปฌ๋Ÿผ์œผ๋กœ์„œ ๋™์ž‘ํ•˜์ง€๋Š” ์•Š๋Š”๋‹ค.

 

 

๐Ÿ’ฌ mysql

mysql์˜ ๊ฒฝ์šฐ binary๋ผ๋Š” ํƒ€์ž…์„ ํ™œ์šฉํ•˜์—ฌ ํ•„๋“œ๊ฐ€ ์ƒ์„ฑ์ด ๋œ๋‹ค.

๋งˆ์ฐฌ๊ฐ€์ง€๋กœ ์ž๋™ ์ฆ๊ฐ€๋กœ ๊ด€๋ฆฌ๋˜์ง€ ์•Š๊ณ , ๋ณ„๋„์˜ ์‹œํ€€์Šค ํ…Œ์ด๋ธ”์ด ์ƒ์„ฑ๋˜์ง€ ์•Š๋Š”๋‹ค.

 


๐Ÿ’ฌ postgresql

h2์™€ ๋™์ผํ•˜๊ฒŒ uuid๋ผ๋Š” ํ•„๋“œ๊ฐ’์œผ๋กœ ์ƒ์„ฑ๋œ๋‹ค.

 



๐ŸŒฑ @IdGeneratorType

@TableGenerator, @SequenceGenerator ์™ธ์—๋„ ๋ฒ”์šฉ์ ์œผ๋กœ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋Š” @GenericGenerator๋ผ๋Š” ์–ด๋…ธํ…Œ์ด์…˜์ด ์กด์žฌํ•œ๋‹ค.
ํ•˜์ง€๋งŒ, ๊ณต์‹ ๋ฌธ์„œ์—์„œ @IdGeneratorType์„ ๋Œ€์‹  ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์„ ๊ถŒ๊ณ ํ•˜์˜€๊ธฐ ๋•Œ๋ฌธ์— ์‚ฌ์‹ค์ƒ deprecated ๋˜์—ˆ๋‹ค๊ณ  ์ƒ๊ฐํ•œ๋‹ค.
@IdGeneratorType์„ ์‚ฌ์šฉํ•˜๋ฉด ์–ด๋…ธํ…Œ์ด์…˜์ด ์•„๋‹Œ ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ํ™œ์šฉํ•˜์—ฌ ์กฐ๊ธˆ ๋” ์„ธ์„ธํ•˜๊ฒŒ ์ปค์Šคํ…€์„ ์ง„ํ–‰ํ•  ์ˆ˜ ์žˆ๋‹ค.

 

public class CustomSequenceGenerator implements IdentifierGenerator {

	public CustomSequenceGenerator(
			Sequence config,
			Member annotatedMember,
			CustomIdGeneratorCreationContext context) {
		//...
	}

	@Override
	public Object generate(
			SharedSessionContractImplementor session,
			Object object) {
		//...
}

@IdGeneratorType( CustomSequenceGenerator.class )
@Target({METHOD, FIELD})
@Retention(RUNTIME)
public @interface Sequence {
	String name();
	int startWith() default 1;
	int incrementBy() default 50;
	Class<? extends Optimizer> optimizer() default Optimizer.class;
}

 

์‚ฌ์‹ค ์ง์ ‘ ์‚ฌ์šฉํ•  ์ผ์€ ์—†์„ ๊ฒƒ ๊ฐ™์•„์„œ ๊ทธ๋ƒฅ Member ์œ„์— @Sequence๋ผ๋Š” ์ปค์Šคํ…€ ์–ด๋…ธํ…Œ์ด์…˜์ด ์ ์šฉ๋˜์—ˆ์„ ๊ฒฝ์šฐ๋ฅผ ๋ณด์—ฌ์ฃผ๋Š” ์˜ˆ์ œ ์ฝ”๋“œ๋ฅผ ๊ฐ€์ ธ์™”๋‹ค.

 

public class TableGenerator implements PersistentIdentifierGenerator {
	...
  @Override
  public Object generate(final SharedSessionContractImplementor session, final Object obj) {
    final SqlStatementLogger statementLogger = session.getFactory().getServiceRegistry()
            .getService( JdbcServices.class )
            .getSqlStatementLogger();
    final SessionEventListenerManager statsCollector = session.getEventListenerManager();

    return optimizer.generate(
            new AccessCallback() {
              @Override
              public IntegralDataTypeHolder getNextValue() {
                return session.getTransactionCoordinator().createIsolationDelegate().delegateWork(
                        new AbstractReturningWork<>() {
                          @Override
                          public IntegralDataTypeHolder execute(Connection connection) throws SQLException {
                            return nextValue( connection, statementLogger, statsCollector );
                          }
                        },
                        true
                );
              }

              @Override
              public String getTenantIdentifier() {
                return session.getTenantIdentifier();
              }
            }
    );
  }
}

 

์‹ค์ œ๋กœ @TableGenerator ์—ญ์‹œ IdentifierGenerator ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ํ™œ์šฉํ•˜์—ฌ ๊ตฌํ˜„๋˜์–ด ์žˆ๋Š” ๊ฒƒ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋‹ค.

 



๐ŸŒฑ ์•„์˜ˆ ์•„๋ฌด๊ฒƒ๋„ ๋ถ™์ด์ง€ ์•Š๋Š”๋‹ค๋ฉด?

@Entity
class User(
    @Id
    val id: Long = 0L
)

@GenerateType์„ ์•„์˜ˆ ๋ถ™์ด์ง€ ์•Š์•„๋„ ๋˜๋Š”์ง€ ๊ถ๊ธˆํ•ด์„œ ์‹คํ—˜ํ•ด๋ณด์•˜๋‹ค.

 


๐Ÿ’ฌ h2 database

๊ธฐ๋ณธ์ ์œผ๋กœ user table๋งŒ ์ƒ์„ฑํ•˜๊ณ , id์—๋„ auto_increment ๊ฐ™์ด ๊ด€๋ฆฌํ•˜๋Š” ์กฐ๊ฑด์ด ๋“ค์–ด๊ฐ€์ง€ ์•Š๋Š”๋‹ค.

์ด ์ƒํƒœ๋กœ ์‚ฝ์ž…์„ ํ•˜๊ฒŒ ๋˜๋ฉด ๋‹ค์Œ๊ณผ ๊ฐ™๋‹ค.

userRepository.save(User())

 

id์— ๋Œ€ํ•œ ๋ฐ”์ธ๋”ฉ์ด 0์œผ๋กœ ๋“ค์–ด๊ฐ„ ๊ฒƒ์„ ๋ณผ ์ˆ˜ ์žˆ๋‹ค.

 

userRepository.save(User())
userRepository.save(User())

๋˜ํ•œ, save๋ฅผ 2๋ฒˆ ํ˜ธ์ถœํ•˜๊ฒŒ ๋˜๋ฉด์€ ์œ„์™€ ๊ฐ™์ด ์ค‘๋ณต๋œ ์‹๋ณ„์ž๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค๋Š” ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ•œ๋‹ค. (PK๋Š” unique ํ•ด์•ผ ํ•˜๋‹ˆ๊นŒ)

 

์ด๋Š” PK ๊ฐ’์— ๋Œ€ํ•ด ๋ณ„๋„๋กœ ๊ด€๋ฆฌํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ์ง€์ •ํ•˜์ง€ ์•Š์•˜๊ธฐ ๋•Œ๋ฌธ์— ์‚ฌ์šฉ์ž๊ฐ€ ์ง์ ‘ id๋ฅผ ๋„ฃ์–ด์ค˜์•ผ ๋˜๋ฉด์„œ ์ƒ๊ธด ๋ฌธ์ œ์ด๋‹ค. ์šฐ์„  ์—”ํ‹ฐํ‹ฐ ์ƒ์„ฑ ์‹œ ์•„์ด๋””์— ๋Œ€ํ•œ ๊ธฐ๋ณธ๊ฐ’์ธ 0L์„ ์ง€์ •ํ•˜๋ฉด์„œ ๋˜ ๋‹ค์‹œ '0L'์ด๋ผ๋Š” ๋™์ผํ•œ ํ‚ค๋ฅผ ๊ฐ€์ง„ ์—”ํ‹ฐํ‹ฐ๊ฐ€ ์‚ฝ์ž…๋˜๋ฉด์„œ ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ•œ ๊ฒƒ์ด๋‹ค.๊ทธ๋ž˜์„œ ๋ณตํ•ฉํ‚ค ๊ฐ™์€ ํŠน์ˆ˜ ์ƒํ™ฉ์„ ์ œ์™ธํ•˜๋ฉด ์›ฌ๋งŒํ•˜๋ฉด ์ƒ์„ฑ ์ „๋žต์„ ํ†ตํ•ด์„œ ๊ด€๋ฆฌํ•˜๋Š” ๊ฒŒ ์ข‹๋‹ค๋Š” ์ƒ๊ฐ์ด ๋“ค์—ˆ๋‹ค.

 


๐Ÿ’ฌ mysql

์ž‘๋™ ๊ณผ์ •์€ ์•ž๊ณผ ๋˜‘๊ฐ™๊ธฐ ๋•Œ๋ฌธ์— ๋ณ„๋„๋กœ ์„ค๋ช…ํ•˜์ง€ ์•Š๊ณ , ํ…Œ์ด๋ธ” ํ˜•์‹๋งŒ ๋ณด๊ฒ ๋‹ค.

๋งˆ์ฐฌ๊ฐ€์ง€๋กœ ๋‹จ์ˆœํžˆ ํ…Œ์ด๋ธ”์˜ ํ•„๋“œ๊ฐ’์œผ๋กœ bigint๋งŒ ์กด์žฌํ•˜๋Š” ๊ฒƒ์„ ๋ณผ ์ˆ˜ ์žˆ๋‹ค.

 


๐Ÿ’ฌ postgresql

h2์™€ ๋™์ผํ•˜๊ฒŒ ์ƒ์„ฑ๋œ ๊ฒƒ์„ ๋ณผ ์ˆ˜ ์žˆ๋‹ค.

 



๐ŸŒฑ ๊ธฐ๋ณธ๊ฐ’์„ ํ• ๋‹นํ•ด์ฃผ์ง€ ์•Š์•˜๋‹ค๋ฉด?

์—ฌ๊ธฐ์„œ๋„ ๊ธฐ๋ณธ๊ฐ’์„ ์–ด๋–ป๊ฒŒ ํ• ๋‹นํ•˜๋Š”์ง€์— ๋”ฐ๋ผ์„œ ๊ฒฐ๊ณผ๊ฐ€ ๋‹ฌ๋ผ์ง„๋‹ค. (generatedType์„ ์ง€์ •ํ•˜์ง€ ์•Š์•˜์„ ๋•Œ์˜ ๊ฒฐ๊ณผ)

@Entity
class User(
    @Id
    val id: Long = 0L
)

ํ”ํžˆ ์‚ฌ์šฉํ•˜๋Š” Long ํƒ€์ž… id์— 0L ๊ฐ™์€ ๊ธฐ๋ณธ๊ฐ’์œผ๋กœ ์ดˆ๊ธฐํ™”ํ•˜๊ฒŒ ๋œ๋‹ค๋ฉด, ์—”ํ‹ฐํ‹ฐ ์ €์žฅ ์‹œ ๋‹จ์ˆœํžˆ ํ•˜๋‚˜์˜ insert ์ฟผ๋ฆฌ๋งŒ ๋ฐœ์ƒํ•˜๊ฒŒ ๋œ๋‹ค. (Int ํƒ€์ž…๋„ ๋งˆ์ฐฌ๊ฐ€์ง€)

ํ•˜์ง€๋งŒ, 1L ๊ฐ™์ด ํŠน์ •ํ•œ ๊ฐ’์œผ๋กœ ์„ค์ •ํ•˜๊ฒŒ ๋˜๋ฉด select ์ฟผ๋ฆฌ๊ฐ€ ๋ฐœ์ƒํ•˜๊ณ  ๊ทธ ๋‹ค์Œ insert ์ฟผ๋ฆฌ๊ฐ€ ๋ฐœ์ƒํ•œ๋‹ค.

์ด๋Š” ์‚ฝ์ž… ์ „์— ์ด๋ฏธ ํ•ด๋‹น ๋ ˆ์ฝ”๋“œ๊ฐ€ ์กด์žฌํ•˜๋Š”์ง€ ํ™•์ธํ•˜๊ณ  (๊ด€๋ฆฌ ์ „๋žต์„ ์„ค์ •ํ•ด์ฃผ์ง€ ์•Š์•˜์œผ๋‹ˆ๊นŒ) insert๋ฅผ ๋‚ ๋ ค์„œ ์กด์žฌํ•˜์ง€ ์•Š๋Š” ๊ฒƒ์— ๋Œ€ํ•ด์„œ๋งŒ insert๋ฅผ ํ•˜๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค.

 

@Entity
class User(
    @Id @GeneratedValue(strategy = GenerationType.IDENTITY)
    val id: Long = 0L
)

๊ฐ™์€ ์›๋ฆฌ๋กœ IDENTITY๋ฅผ ์„ค์ •ํ•˜๊ฒŒ ๋˜๋ฉด ์• ์ดˆ์— insert ์‹œ ์•„์ด๋””๊ฐ€ ์—†์œผ๋‹ˆ๊นŒ ์• ์ดˆ์— ๊ฒ€์ฆํ•  ๊ฐ’์ด ์—†์œผ๋‹ˆ ๋‹จ์ˆœํžˆ insert๋งŒ ๋ฐœ์ƒํ•œ๋‹ค. (persist ์‹œ์— insert ์ฟผ๋ฆฌ ๋ฐœ์ƒ)

 

@Entity
class User(
    @Id 
    val id: String = ""
)

String์˜ ๊ฒฝ์šฐ ๋ฌด์กฐ๊ฑด select๊ฐ€ ๋ฐœ์ƒํ•œ๋‹ค. (์• ์ดˆ์— String? ํƒ€์ž…์œผ๋กœ ์„ค์ • ํ›„ ๊ธฐ๋ณธ ๊ฐ’์„ null๋กœ ์ง€์ •ํ•˜๋ฉด ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ•œ๋‹ค.)

์ด๋Š”, save() ์‹œ์˜ ๋ฉ”์„œ๋“œ๋ฅผ ๋ณด๋ฉด ํŒŒ์•…ํ•  ์ˆ˜ ์žˆ๋‹ค.

save() ์‹œ ๋ฉ”์„œ๋“œ๋ฅผ ๋ณด๋ฉด ์—”ํ‹ฐํ‹ฐ๊ฐ€ ์ƒˆ๋กœ์šฐ๋ฉด persist, ์•„๋‹ˆ๋ฉด merge๋ฅผ ํ•˜๊ฒŒ ๋˜๋Š” ๊ฑธ ๋ณผ ์ˆ˜ ์žˆ๋‹ค.

์—ฌ๊ธฐ์„œ isNew() ๋ฉ”์„œ๋“œ๋ฅผ ํƒ€๊ณ  ๋“ค์–ด๊ฐ€๋ฉด ๋‹ค์Œ๊ณผ ๊ฐ™๋‹ค.

primitive ํƒ€์ž…์ด ์•„๋‹ˆ๋ผ๋ฉด null๋กœ ์ฒดํฌ, Number ํ˜•์ด๋ผ๋ฉด 0L์œผ๋กœ ์ฒดํฌํ•ด์„œ ์ด๊ฒŒ ์ƒˆ๋กœ์šด ๊ฐ’์ธ์ง€ ํ…Œ์ŠคํŠธํ•˜๊ฒŒ ๋œ๋‹ค.

 

Comments