Search code examples
kotlinmicronautmicronaut-data

Optimistic Locking: unsupported Version type long


I´m trying to use Optimistic Locking with Micronaut Data and Kotlin, but unfortunately it fails with the Exception:

14:33:32.113 [default-nioEventLoopGroup-1-2] ERROR i.m.h.s.netty.RoutingInBoundHandler - Unexpected error occurred: An error occurred invoking pre-persist event listeners: Unsupported @Version type: long
io.micronaut.data.event.PersistenceEventException: An error occurred invoking pre-persist event listeners: Unsupported @Version type: long
    at io.micronaut.data.runtime.event.EntityEventRegistry.prePersist(EntityEventRegistry.java:92)
    at io.micronaut.data.hibernate.event.EventIntegrator.lambda$integrate$9d2e46a6$1(EventIntegrator.java:77)
    at org.hibernate.action.internal.EntityInsertAction.preInsert(EntityInsertAction.java:227)
    at org.hibernate.action.internal.EntityInsertAction.execute(EntityInsertAction.java:100)
    at org.hibernate.engine.spi.ActionQueue.executeActions(ActionQueue.java:604)
    at org.hibernate.engine.spi.ActionQueue.lambda$executeActions$1(ActionQueue.java:478)
    at java.base/java.util.LinkedHashMap.forEach(LinkedHashMap.java:684)
    at org.hibernate.engine.spi.ActionQueue.executeActions(ActionQueue.java:475)
    at org.hibernate.event.internal.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:348)
    at org.hibernate.event.internal.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:40)
    at org.hibernate.event.service.internal.EventListenerGroupImpl.fireEventOnEachListener(EventListenerGroupImpl.java:102)
    at org.hibernate.internal.SessionImpl.doFlush(SessionImpl.java:1362)
    at org.hibernate.internal.SessionImpl.managedFlush(SessionImpl.java:453)
    at org.hibernate.internal.SessionImpl.flushBeforeTransactionCompletion(SessionImpl.java:3212)
    at org.hibernate.internal.SessionImpl.beforeTransactionCompletion(SessionImpl.java:2380)
    at org.hibernate.engine.jdbc.internal.JdbcCoordinatorImpl.beforeTransactionCompletion(JdbcCoordinatorImpl.java:447)
    at org.hibernate.resource.transaction.backend.jdbc.internal.JdbcResourceLocalTransactionCoordinatorImpl.beforeCompletionCallback(JdbcResourceLocalTransactionCoordinatorImpl.java:183)
    at org.hibernate.resource.transaction.backend.jdbc.internal.JdbcResourceLocalTransactionCoordinatorImpl.access$300(JdbcResourceLocalTransactionCoordinatorImpl.java:40)
    at org.hibernate.resource.transaction.backend.jdbc.internal.JdbcResourceLocalTransactionCoordinatorImpl$TransactionDriverControlImpl.commit(JdbcResourceLocalTransactionCoordinatorImpl.java:281)
...
    

My setup looks like this (should be pretty much like the docs):

import javax.persistence.Column
import javax.persistence.Entity
import javax.persistence.EnumType
import javax.persistence.Enumerated
import javax.persistence.GeneratedValue
import javax.persistence.Id
import javax.persistence.Table
import javax.persistence.Version

@Entity
@Table(name = "invoice_queue")
data class InvoiceQueueEntity(
    @Id
    @GeneratedValue
    var id: Long = 0,

    ...(things left out for privacy reasons)...

    @Version
    var version: Long = 0L,
)

The migrations creating the table are:

create table invoice_queue
(
    id      int8         not null,
    primary key (id)
);

create sequence hibernate_sequence start 1 increment 1;
alter table if exists invoice_queue
    add column version int8 not null default 0;

Am I missing something?


Solution

  • If you are sure that you are using javax.persistence.Version and not io.micronaut.core.version.annotation.Version, then the problem is probably that the java field has a primitive type.

    If you make it nullable, you should get the boxed type. Try:

    var version: Long? = 0L