I have a composite unique constraint in the database and i wish to violate it inside the transaction but it will be upheld after i call commit.
It's pretty basic database transaction, but i am not aware how to achieve it using JPA.
I have already tried @org.springframework.transaction.annotation.Transactional on my @org.springframework.stereotype.Service class and also at the method level.
but the moment i call userRepository.save(userEntity) it throws
java.sql.SQLIntegrityConstraintViolationException: (conn=380) Duplicate entry ...'
controller
@PostMapping("/save")
@Transactional
fun createUser(
@RequestHeader("token", required = true) subject: String,
): ResponseEntity<*> {
val id = extractId(subject)
return userService.save(id)
}
service
@Transactional
fun save(id: String): ResponseEntity<*> {
val validatedUser = getValidatedUser(id)
return ResponseEntity<User>(validatedUser, HttpStatus.CREATED)
}
@Transactional
fun getValidatedUser(id: String): User? {
var list = listOf(User(id))
val newUser = //some logic to generate user
userRepository.saveAll(list.plus(newUser)) // <--- where error happens
}
You are looking for DEFERRED constraints.
Simplified example (postgresql) that mimics your actions:
using
deferrableandset constraints deferred:using
deferrable initially deferredyou can skipset constraints deferred:So, the easiest solution would be to add
deferrable initially deferredto your constraint definition.