diff --git a/src/main/kotlin/org/gitanimals/render/domain/AbstractTime.kt b/src/main/kotlin/org/gitanimals/render/domain/AbstractTime.kt index 0b86180..85f6ec8 100644 --- a/src/main/kotlin/org/gitanimals/render/domain/AbstractTime.kt +++ b/src/main/kotlin/org/gitanimals/render/domain/AbstractTime.kt @@ -2,6 +2,7 @@ package org.gitanimals.render.domain import jakarta.persistence.Column import jakarta.persistence.MappedSuperclass +import jakarta.persistence.PrePersist import org.springframework.data.annotation.CreatedDate import org.springframework.data.annotation.LastModifiedDate import java.time.Instant @@ -14,5 +15,14 @@ abstract class AbstractTime( @LastModifiedDate @Column(name = "modified_at") - val modifiedAt: Instant = createdAt, -) + var modifiedAt: Instant? = null, +) { + + @PrePersist + fun prePersist() { + modifiedAt = when (modifiedAt == null) { + true -> createdAt + false -> return + } + } +} diff --git a/src/main/kotlin/org/gitanimals/render/domain/Persona.kt b/src/main/kotlin/org/gitanimals/render/domain/Persona.kt index e22ccb3..da8f6a1 100644 --- a/src/main/kotlin/org/gitanimals/render/domain/Persona.kt +++ b/src/main/kotlin/org/gitanimals/render/domain/Persona.kt @@ -26,6 +26,10 @@ class Persona( @JoinColumn(name = "user_id") @ManyToOne(fetch = FetchType.LAZY, optional = false) var user: User? = null, + + @Version + @Column(name = "version", nullable = false) + var version: Long? = null, ) : AbstractTime() { constructor( diff --git a/src/main/kotlin/org/gitanimals/render/domain/UserService.kt b/src/main/kotlin/org/gitanimals/render/domain/UserService.kt index f55ee71..0264459 100644 --- a/src/main/kotlin/org/gitanimals/render/domain/UserService.kt +++ b/src/main/kotlin/org/gitanimals/render/domain/UserService.kt @@ -49,6 +49,7 @@ class UserService( fun createNewUser(name: String, contributions: Map): User = userRepository.save(User.newUser(name, contributions)) + @Retryable(retryFor = [ObjectOptimisticLockingFailureException::class], maxAttempts = 100) @Transactional fun giveBonusPersona(id: Long, persona: String) { requireIdempotency("$id:bonus") @@ -58,6 +59,7 @@ class UserService( user.giveBonusPersona(persona) } + @Retryable(retryFor = [ObjectOptimisticLockingFailureException::class], maxAttempts = 100) @Transactional fun changePersona(id: Long, personChangeRequest: PersonaChangeRequest) { val user = getUserById(id)