micronaut-projects/micronaut-data

findBy..ForUpdate not Working

Closed this issue · 2 comments

Expected Behavior

Una Repository Interfaze is expected ( as the documentation explains) that when defining a fun findAllByTypeAndStatusForUpdate method a SELECT FOR UPDATE query is generated

Actual Behaviour

A repository like

`import io.micronaut.data.annotation.Query
import io.micronaut.data.annotation.Repository
import io.micronaut.data.model.Pageable
import io.micronaut.data.repository.CrudRepository

import switchfleet.api.tasks.domain.TaskStatus
import switchfleet.api.tasks.domain.TaskType
import switchfleet.api.tasks.domain.Tasks
import java.util.UUID

@repository
interface TaskRepository : CrudRepository<Tasks, UUID> {

@query("FROM Tasks tasks WHERE tasks.type = :type AND tasks.status = :status")
fun findAllByTypeAndStatusForUpdate(type: TaskType, status: TaskStatus, pageable: Pageable): List
}

Doen no generate the SELECT FOR UPDATE

`

Steps To Reproduce

I am using Micronaut 4.6.1

Code

Repository

`import io.micronaut.data.annotation.Query
import io.micronaut.data.annotation.Repository
import io.micronaut.data.model.Pageable
import io.micronaut.data.repository.CrudRepository

import switchfleet.api.tasks.domain.TaskStatus
import switchfleet.api.tasks.domain.TaskType
import switchfleet.api.tasks.domain.Tasks
import java.util.UUID

@repository
interface TaskRepository : CrudRepository<Tasks, UUID> {

@query("FROM Tasks tasks WHERE tasks.type = :type AND tasks.status = :status")
fun findAllByTypeAndStatusForUpdate(type: TaskType, status: TaskStatus, pageable: Pageable): List
}
`

Entity

`
package switchfleet.api.tasks.domain

import io.micronaut.data.annotation.DateCreated
import io.micronaut.serde.annotation.Serdeable
import jakarta.persistence.*
import java.time.LocalDateTime
import java.util.*

enum class TaskStatus {
PENDING, DONE, IN_PROGRESS
}

enum class TaskType {
SEND_EMAIL,
}

@Serdeable
@entity
@table(name = "tasks")
data class Tasks(

@id
@column(name = "id", nullable = false)
val id: UUID,

@Enumerated(value = EnumType.STRING)
val type:TaskType,

@column(name = "metadata", nullable = false, unique = false)
val metadata: String,

@Enumerated(value = EnumType.STRING)
var status: TaskStatus = TaskStatus.PENDING,

@field:DateCreated
@column(name = "created_at", nullable = false)
val createdAt: LocalDateTime = LocalDateTime.now(),

@field:DateCreated
@column(name = "updated_at", nullable = false)
val updatedAt: LocalDateTime = LocalDateTime.now()

)
`

Environment Information

  • MacOS
  • PostgresQL
  • Micronau t4.6.1

Example Application

No response

Version

4.6.1

I think you can use Micronaut Data @QueryHint annotation to have for update query in Hibernate.
You can replace this method

@Query("FROM Tasks tasks WHERE tasks.type = :type AND tasks.status = :status")
fun findAllByTypeAndStatusForUpdate(type: TaskType, status: TaskStatus, pageable: Pageable): List

with this (don't have to use @Query although you can)

@QueryHint(name = "org.hibernate.lockMode", value = "pessimistic_write")
fun findAllByTypeAndStatus(type: TaskType, status: TaskStatus, pageable: Pageable): List

findForUpdate is supported only for jdbc/r2dbc and for jpa the suggestion in the comment above can be used.
I think we can close this, please reopen if you think it needs some changes.