micronaut-data
micronaut-data copied to clipboard
Error when kotlin data class contains a property start with "is"
Task List
- [x] Steps to reproduce provided
- [x] Stacktrace (if present) provided
- [ ] Example that reproduces the problem uploaded to Github
- [ ] Full description of the issue provided (see below)
Steps to Reproduce
- Create a kotlin app
- Add entity, repository, controller class
@Entity
data class Room(
@Id
var id: Int,
var name: String,
var isPublic: Boolean,
)
@Repository
interface RoomRepository: JpaRepository<Room, Int>
@Controller("/rooms")
class RoomController(private val roomRepository: RoomRepository) {
@Get
fun index(): List<Room> {
return roomRepository.findAll()
}
}
- Request the endpoint
curl localhost:5000/rooms
{"message":"Internal Server Error: Constructor argument [isPublic] for type [upgrade.kotlin.Room] must have an associated getter","_links":{"self":{"href":"/rooms","templated":false}}}
Expected Behaviour
No exception. It works in Micronaut 2.3.4.
Actual Behaviour
14:36:59.149 [default-nioEventLoopGroup-1-5] ERROR i.m.h.s.netty.RoutingInBoundHandler - Unexpected error occurred: Constructor argument [isPublic] for type [upgrade.kotlin.Room] must have an associated getter
io.micronaut.data.exceptions.MappingException: Constructor argument [isPublic] for type [upgrade.kotlin.Room] must have an associated getter
at io.micronaut.data.model.runtime.RuntimePersistentEntity.<init>(RuntimePersistentEntity.java:105)
at io.micronaut.data.model.runtime.RuntimePersistentEntity.<init>(RuntimePersistentEntity.java:55)
at io.micronaut.data.runtime.support.DefaultRuntimeEntityRegistry$1.<init>(DefaultRuntimeEntityRegistry.java:73)
at io.micronaut.data.runtime.support.DefaultRuntimeEntityRegistry.newEntity(DefaultRuntimeEntityRegistry.java:73)
at io.micronaut.data.runtime.support.DefaultRuntimeEntityRegistry.getEntity(DefaultRuntimeEntityRegistry.java:64)
at io.micronaut.data.hibernate.event.EventIntegrator.lambda$integrate$b7f772e6$1(EventIntegrator.java:152)
at org.hibernate.event.service.internal.EventListenerGroupImpl.fireEventOnEachListener(EventListenerGroupImpl.java:102)
at org.hibernate.internal.FastSessionServices.firePostLoadEvent(FastSessionServices.java:295)
at org.hibernate.engine.internal.TwoPhaseLoad.postLoad(TwoPhaseLoad.java:512)
at org.hibernate.loader.Loader.initializeEntitiesAndCollections(Loader.java:1231)
at org.hibernate.loader.Loader.processResultSet(Loader.java:1001)
at org.hibernate.loader.Loader.doQuery(Loader.java:959)
at org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:349)
at org.hibernate.loader.Loader.doList(Loader.java:2850)
at org.hibernate.loader.Loader.doList(Loader.java:2832)
at org.hibernate.loader.Loader.listIgnoreQueryCache(Loader.java:2664)
at org.hibernate.loader.Loader.list(Loader.java:2659)
at org.hibernate.loader.hql.QueryLoader.list(QueryLoader.java:506)
at org.hibernate.hql.internal.ast.QueryTranslatorImpl.list(QueryTranslatorImpl.java:400)
at org.hibernate.engine.query.spi.HQLQueryPlan.performList(HQLQueryPlan.java:219)
at org.hibernate.internal.SessionImpl.list(SessionImpl.java:1414)
at org.hibernate.query.internal.AbstractProducedQuery.doList(AbstractProducedQuery.java:1625)
at org.hibernate.query.internal.AbstractProducedQuery.list(AbstractProducedQuery.java:1593)
at org.hibernate.query.criteria.internal.compile.CriteriaQueryTypeQueryAdapter.list(CriteriaQueryTypeQueryAdapter.java:96)
at io.micronaut.data.hibernate.operations.HibernateJpaOperations.lambda$findAll$2(HibernateJpaOperations.java:267)
at io.micronaut.transaction.support.AbstractSynchronousTransactionManager.executeRead(AbstractSynchronousTransactionManager.java:155)
at io.micronaut.data.hibernate.operations.HibernateJpaOperations.findAll(HibernateJpaOperations.java:262)
at io.micronaut.data.runtime.intercept.DefaultFindAllInterceptor.intercept(DefaultFindAllInterceptor.java:63)
at io.micronaut.data.runtime.intercept.DefaultFindAllInterceptor.intercept(DefaultFindAllInterceptor.java:36)
at io.micronaut.data.intercept.DataIntroductionAdvice.intercept(DataIntroductionAdvice.java:80)
at io.micronaut.aop.chain.MethodInterceptorChain.proceed(MethodInterceptorChain.java:96)
at io.micronaut.validation.ValidatingInterceptor.intercept(ValidatingInterceptor.java:137)
at io.micronaut.aop.chain.MethodInterceptorChain.proceed(MethodInterceptorChain.java:96)
at upgrade.kotlin.RoomRepository$Intercepted.findAll(Unknown Source)
at upgrade.kotlin.RoomController.index(RoomController.kt:10)
at upgrade.kotlin.$RoomControllerDefinition$$exec1.invokeInternal(Unknown Source)
at io.micronaut.context.AbstractExecutableMethod.invoke(AbstractExecutableMethod.java:151)
at io.micronaut.context.DefaultBeanContext$4.invoke(DefaultBeanContext.java:482)
at io.micronaut.web.router.AbstractRouteMatch.execute(AbstractRouteMatch.java:255)
at io.micronaut.web.router.RouteMatch.execute(RouteMatch.java:118)
at io.micronaut.http.server.netty.RoutingInBoundHandler.lambda$buildResultEmitter$12(RoutingInBoundHandler.java:1397)
at io.reactivex.internal.operators.flowable.FlowableDefer.subscribeActual(FlowableDefer.java:35)
at io.reactivex.Flowable.subscribe(Flowable.java:14935)
at io.reactivex.Flowable.subscribe(Flowable.java:14882)
at io.micronaut.reactive.rxjava2.RxInstrumentedFlowable.subscribeActual(RxInstrumentedFlowable.java:57)
at io.reactivex.Flowable.subscribe(Flowable.java:14935)
at io.reactivex.Flowable.subscribe(Flowable.java:14882)
at io.reactivex.internal.operators.flowable.FlowableDefer.subscribeActual(FlowableDefer.java:42)
at io.reactivex.Flowable.subscribe(Flowable.java:14935)
at io.reactivex.Flowable.subscribe(Flowable.java:14882)
at io.micronaut.reactive.rxjava2.RxInstrumentedFlowable.subscribeActual(RxInstrumentedFlowable.java:57)
at io.reactivex.Flowable.subscribe(Flowable.java:14935)
at io.reactivex.Flowable.subscribe(Flowable.java:14882)
at io.micronaut.http.server.context.ServerRequestContextFilter.lambda$doFilter$0(ServerRequestContextFilter.java:62)
at io.reactivex.internal.operators.flowable.FlowableFromPublisher.subscribeActual(FlowableFromPublisher.java:29)
at io.reactivex.Flowable.subscribe(Flowable.java:14935)
at io.reactivex.Flowable.subscribe(Flowable.java:14885)
at io.micronaut.http.server.netty.RoutingInBoundHandler.lambda$buildExecutableRoute$8(RoutingInBoundHandler.java:1102)
at io.micronaut.web.router.DefaultUriRouteMatch$1.execute(DefaultUriRouteMatch.java:80)
at io.micronaut.web.router.RouteMatch.execute(RouteMatch.java:118)
at io.micronaut.http.server.netty.RoutingInBoundHandler.handleRouteMatch(RoutingInBoundHandler.java:726)
at io.micronaut.http.server.netty.RoutingInBoundHandler.channelRead0(RoutingInBoundHandler.java:588)
at io.micronaut.http.server.netty.RoutingInBoundHandler.channelRead0(RoutingInBoundHandler.java:151)
at io.netty.channel.SimpleChannelInboundHandler.channelRead(SimpleChannelInboundHandler.java:99)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:379)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:365)
at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:357)
at io.netty.channel.SimpleChannelInboundHandler.channelRead(SimpleChannelInboundHandler.java:102)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:379)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:365)
at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:357)
at io.netty.handler.codec.MessageToMessageDecoder.channelRead(MessageToMessageDecoder.java:103)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:379)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:365)
at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:357)
at io.micronaut.http.netty.stream.HttpStreamsHandler.channelRead(HttpStreamsHandler.java:199)
at io.micronaut.http.netty.stream.HttpStreamsServerHandler.channelRead(HttpStreamsServerHandler.java:121)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:379)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:365)
at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:357)
at io.netty.handler.codec.MessageToMessageDecoder.channelRead(MessageToMessageDecoder.java:103)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:379)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:365)
at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:357)
at io.netty.handler.codec.MessageToMessageDecoder.channelRead(MessageToMessageDecoder.java:103)
at io.netty.handler.codec.MessageToMessageCodec.channelRead(MessageToMessageCodec.java:111)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:379)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:365)
at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:357)
at io.netty.channel.ChannelInboundHandlerAdapter.channelRead(ChannelInboundHandlerAdapter.java:93)
at io.netty.handler.codec.http.HttpServerKeepAliveHandler.channelRead(HttpServerKeepAliveHandler.java:64)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:379)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:365)
at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:357)
at io.netty.handler.flow.FlowControlHandler.dequeue(FlowControlHandler.java:200)
at io.netty.handler.flow.FlowControlHandler.channelRead(FlowControlHandler.java:162)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:379)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:365)
at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:357)
at io.netty.channel.CombinedChannelDuplexHandler$DelegatingChannelHandlerContext.fireChannelRead(CombinedChannelDuplexHandler.java:436)
at io.netty.handler.codec.ByteToMessageDecoder.fireChannelRead(ByteToMessageDecoder.java:324)
at io.netty.handler.codec.ByteToMessageDecoder.channelRead(ByteToMessageDecoder.java:296)
at io.netty.channel.CombinedChannelDuplexHandler.channelRead(CombinedChannelDuplexHandler.java:251)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:379)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:365)
at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:357)
at io.netty.handler.timeout.IdleStateHandler.channelRead(IdleStateHandler.java:286)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:379)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:365)
at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:357)
at io.netty.channel.DefaultChannelPipeline$HeadContext.channelRead(DefaultChannelPipeline.java:1410)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:379)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:365)
at io.netty.channel.DefaultChannelPipeline.fireChannelRead(DefaultChannelPipeline.java:919)
at io.netty.channel.nio.AbstractNioByteChannel$NioByteUnsafe.read(AbstractNioByteChannel.java:166)
at io.netty.channel.nio.NioEventLoop.processSelectedKey(NioEventLoop.java:719)
at io.netty.channel.nio.NioEventLoop.processSelectedKeysOptimized(NioEventLoop.java:655)
at io.netty.channel.nio.NioEventLoop.processSelectedKeys(NioEventLoop.java:581)
at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:493)
at io.netty.util.concurrent.SingleThreadEventExecutor$4.run(SingleThreadEventExecutor.java:989)
at io.netty.util.internal.ThreadExecutorMap$2.run(ThreadExecutorMap.java:74)
at io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30)
at java.lang.Thread.run(Thread.java:748)
Environment Information
- Operating System: Windows 10
- Micronaut Version: 2.4.0
- JDK Version: 1.8
To reproduce the issue, insert some data to the room
table。
Temp workaround is moving the isPublic
constructor parameter to the class body:
@Entity
data class Room(
@Id
var id: Int,
var name: String,
) {
var isPublic: Boolean = true
}
This also happens for non data classes. The following will cause the same issue.
@Entity
class SomeClass(
@Id
val id: Long,
isPublic: Boolean,
) {
var isPublic: Boolean = isPublic
set(isPublic) = ...
}
And can be workaround when renaming the constructor parameter from isPublic
to canBePublic
@Entity
class SomeClass(
@Id
val id: Long,
canBePublic: Boolean,
) {
var isPublic: Boolean = canBePublic
set(isPublic) = ...
}
I just hit this the other day. Here is a quick workaround if you hadn't already figured it out.
@Entity
data class Room(
@Id
var id: Int,
var name: String,
@field:MappedProperty("isPublic")
var public: Boolean,
)
Just for reference, the same issue in different module: https://github.com/micronaut-projects/micronaut-openapi/issues/616
I just got the same issue. Just keeping the issue active.
i can confirm, issue still exists on micronaut 3.3.0 and micronaut-data 3.2.2
@graemerocher is this something that will be resolved by KSP?
A workaround for this is:
@get:JvmName("getIsImportant")
val isImportant: Boolean
@rawilder Very useful workaround—thanks for posting that!
bump
Attempted fix and discussion about such going on here: https://github.com/micronaut-projects/micronaut-core/pull/7058