Я пытаюсь использовать Micronaut с Gorm Standalone без удачи. У меня многопроектная конфигурация gradle. Один проект содержит классы домена, а другой - проект API.
Я получаю эту ошибку, когда пытаюсь сохранить экземпляр (я думаю, что ошибка выдается при попытке закодировать его в json с Джексоном) : ERROR i.m.h.s.netty.RoutingInBoundHandler - Unexpected error occurred: Error encoding object [test.Laboratory : 1] to JSON: Could not obtain current Hibernate Session; nested exception is org.hibernate.HibernateException: No Session found for current thread (through reference chain: test.Laboratory["attached"])
Весь проект имеет такую структуру:
- Root
-- Api
-- Domain classes
Root проект
Проект root имеет это settings.gradle
файл:
include 'api'
include 'domain'
rootProject.name = 'medications'
Доменный проект
settings.gradle
rootProject.name = 'domain'
gradle.properties
micronautVersion=1.2.9
build.gradle
plugins {
id 'groovy'
}
dependencies {
compile 'org.codehaus.groovy:groovy-all:2.5.6'
implementation "io.micronaut.configuration:micronaut-hibernate-validator"
compile 'io.micronaut.configuration:micronaut-hibernate-gorm'
implementation "org.grails:grails-datastore-gorm-hibernate5:7.0.1.RELEASE"
runtime 'org.apache.tomcat:tomcat-jdbc'
runtime 'com.h2database:h2'
compileOnly platform("io.micronaut:micronaut-bom:$micronautVersion")
compileOnly "io.micronaut:micronaut-inject-groovy"
implementation platform("io.micronaut:micronaut-bom:$micronautVersion")
testCompileOnly platform("io.micronaut:micronaut-bom:$micronautVersion")
testImplementation platform("io.micronaut:micronaut-bom:$micronautVersion")
testImplementation("org.spockframework:spock-core") {
exclude group: "org.codehaus.groovy", module: "groovy-all"
}
testImplementation "io.micronaut:micronaut-inject-groovy"
testImplementation "io.micronaut.test:micronaut-test-spock"
testImplementation "io.micronaut.test:micronaut-test-junit5"
testRuntimeOnly "org.junit.vintage:junit-vintage-engine:5.5.0"
}
repositories {
jcenter()
mavenCentral()
maven { url "https://jcenter.bintray.com" }
}
Внутри src/main/groovy/test
:
package test
import grails.gorm.annotation.Entity
import org.grails.datastore.gorm.GormEntity
@Entity
class Laboratory implements GormEntity<Laboratory> {
String name
}
API
settings.gradle
rootProject.name="api"
gradle.properties
micronautVersion=1.2.9
build.gradle
plugins {
id "groovy"
id "io.spring.dependency-management" version "1.0.6.RELEASE"
id "com.github.johnrengelman.shadow" version "5.2.0"
id "application"
}
version "0.1"
group "medications.api"
apply plugin:"application"
apply plugin:"groovy"
repositories {
mavenCentral()
maven { url "https://jcenter.bintray.com" }
}
configurations {
developmentOnly
}
dependencies {
compile 'org.codehaus.groovy:groovy-all:2.5.6'
compile project(':domain')
implementation "io.micronaut.configuration:micronaut-hibernate-validator"
compile 'io.micronaut.configuration:micronaut-hibernate-gorm'
implementation "org.grails:grails-datastore-gorm-hibernate5:7.0.1.RELEASE"
runtime "org.apache.tomcat:tomcat-jdbc:8.5.0"
runtime "org.apache.tomcat.embed:tomcat-embed-logging-log4j:8.5.0"
runtime "org.slf4j:slf4j-api:1.7.10"
runtime 'com.h2database:h2'
compileOnly platform("io.micronaut:micronaut-bom:$micronautVersion")
compileOnly "io.micronaut:micronaut-inject-groovy"
implementation platform("io.micronaut:micronaut-bom:$micronautVersion")
implementation "io.micronaut:micronaut-http-client"
implementation 'io.micronaut:micronaut-http-server-netty'
implementation "io.micronaut:micronaut-runtime-groovy"
implementation "io.micronaut:micronaut-validation"
runtime 'org.postgresql:postgresql:42.2.4'
runtimeOnly "ch.qos.logback:logback-classic:1.2.3"
testCompileOnly platform("io.micronaut:micronaut-bom:$micronautVersion")
testImplementation platform("io.micronaut:micronaut-bom:$micronautVersion")
testImplementation("org.spockframework:spock-core") {
exclude group: "org.codehaus.groovy", module: "groovy-all"
}
testCompileOnly "io.micronaut:micronaut-inject-groovy"
testImplementation "io.micronaut:micronaut-inject-groovy"
testImplementation "io.micronaut.test:micronaut-test-spock"
testImplementation "io.micronaut.test:micronaut-test-junit5"
testImplementation "org.grails:grails-datastore-gorm-hibernate5"
testRuntimeOnly "org.junit.vintage:junit-vintage-engine:5.5.0"
}
test.classpath += configurations.developmentOnly
mainClassName = "test.Application"
shadowJar {
mergeServiceFiles()
}
run.classpath += configurations.developmentOnly
run.jvmArgs('-noverify', '-XX:TieredStopAtLevel=1', '-Dcom.sun.management.jmxremote')
tasks.withType(GroovyCompile) {
groovyOptions.forkOptions.jvmArgs.add('-Dgroovy.parameters=true')
}
src/main/resources/application.yml
---
micronaut:
application:
name: api
---
datasources.default: {}
---
hibernate:
hbm2ddl:
auto: create
dataSource:
url: jdbc:postgresql://${db.host}:${db.port}/${db.name}
dbCreate: create-drop
driverClassName: org.postgresql.Driver
username: ${db.username}
password: ${db.password}
dialect: POSTGRES
LaboratoryController.groovy
package test.controllers
import grails.gorm.transactions.Transactional
import io.micronaut.http.annotation.Controller
import io.micronaut.http.annotation.Post
import test.Laboratory
import test.services.LaboratoryService
@Controller("/laboratory")
@Transactional
class LaboratoryController {
final LaboratoryService laboratoryService
LaboratoryController(LaboratoryService laboratoryService) {
this.laboratoryService = laboratoryService
}
@Post("/")
Laboratory save(Laboratory laboratory) {
return laboratoryService.save(laboratory)
}
}
LaboratoryService.groovy
package test.services
import grails.gorm.services.Service
import groovy.transform.CompileStatic
import test.Laboratory
@Service(Laboratory)
@CompileStatic
abstract class LaboratoryService {
abstract Laboratory save(Laboratory laboratory)
}
Стек ошибок:
api_1 | 03:35:43.195 [pool-2-thread-3] ERROR i.m.h.s.netty.RoutingInBoundHandler - Unexpected error occurred: Error encoding object [test.Laboratory : 1] to JSON: Could not obtain current Hibernate Session; nested exception is org.hibernate.HibernateException: No Session found for current thread (through reference chain: test.Laboratory["attached"])
api_1 | io.micronaut.http.codec.CodecException: Error encoding object [test.Laboratory : 1] to JSON: Could not obtain current Hibernate Session; nested exception is org.hibernate.HibernateException: No Session found for current thread (through reference chain: test.Laboratory["attached"])
api_1 | at io.micronaut.jackson.codec.JsonMediaTypeCodec.encode(JsonMediaTypeCodec.java:176)
api_1 | at io.micronaut.jackson.codec.JsonMediaTypeCodec.encode(JsonMediaTypeCodec.java:182)
api_1 | at io.micronaut.http.server.netty.RoutingInBoundHandler.encodeBodyAsByteBuf(RoutingInBoundHandler.java:1351)
api_1 | at io.micronaut.http.server.netty.RoutingInBoundHandler.encodeBodyWithCodec(RoutingInBoundHandler.java:1297)
api_1 | at io.micronaut.http.server.netty.RoutingInBoundHandler.lambda$subscribeToResponsePublisher$14(RoutingInBoundHandler.java:1232)
api_1 | at io.micronaut.http.server.netty.RoutingInBoundHandler$$Lambda$619.00000000B80B9630.apply(Unknown Source)
api_1 | at io.reactivex.internal.operators.flowable.FlowableMap$MapSubscriber.onNext(FlowableMap.java:63)
api_1 | at io.micronaut.reactive.rxjava2.InstrumentedSubscriber.lambda$onNext$0(InstrumentedSubscriber.java:80)
api_1 | at io.micronaut.reactive.rxjava2.InstrumentedSubscriber$$Lambda$635.0000000084161B60.run(Unknown Source)
api_1 | at io.micronaut.reactive.rxjava2.InstrumentedSubscriber.onNext(InstrumentedSubscriber.java:84)
api_1 | at io.reactivex.internal.operators.flowable.FlowableSwitchMap$SwitchMapSubscriber.drain(FlowableSwitchMap.java:307)
api_1 | at io.reactivex.internal.operators.flowable.FlowableSwitchMap$SwitchMapInnerSubscriber.onSubscribe(FlowableSwitchMap.java:366)
api_1 | at io.micronaut.reactive.rxjava2.InstrumentedSubscriber.onSubscribe(InstrumentedSubscriber.java:75)
api_1 | at io.reactivex.internal.operators.flowable.FlowableJust.subscribeActual(FlowableJust.java:34)
api_1 | at io.reactivex.Flowable.subscribe(Flowable.java:14918)
api_1 | at io.reactivex.Flowable.subscribe(Flowable.java:14865)
api_1 | at io.micronaut.reactive.rxjava2.RxInstrumentedCallableFlowable.subscribeActual(RxInstrumentedCallableFlowable.java:65)
api_1 | at io.reactivex.Flowable.subscribe(Flowable.java:14918)
api_1 | at io.reactivex.Flowable.subscribe(Flowable.java:14865)
api_1 | at io.reactivex.internal.operators.flowable.FlowableSwitchMap$SwitchMapSubscriber.onNext(FlowableSwitchMap.java:129)
api_1 | at io.micronaut.reactive.rxjava2.InstrumentedSubscriber.lambda$onNext$0(InstrumentedSubscriber.java:80)
api_1 | at io.micronaut.reactive.rxjava2.InstrumentedSubscriber$$Lambda$635.0000000084161B60.run(Unknown Source)
api_1 | at io.micronaut.reactive.rxjava2.InstrumentedSubscriber.onNext(InstrumentedSubscriber.java:84)
api_1 | at io.reactivex.internal.operators.flowable.FlowableSubscribeOn$SubscribeOnSubscriber.onNext(FlowableSubscribeOn.java:97)
api_1 | at io.micronaut.reactive.rxjava2.InstrumentedSubscriber.lambda$onNext$0(InstrumentedSubscriber.java:80)
api_1 | at io.micronaut.reactive.rxjava2.InstrumentedSubscriber$$Lambda$635.0000000084161B60.run(Unknown Source)
api_1 | at io.micronaut.reactive.rxjava2.InstrumentedSubscriber.onNext(InstrumentedSubscriber.java:84)
api_1 | at io.micronaut.http.context.ServerRequestTracingPublisher$1.lambda$onNext$1(ServerRequestTracingPublisher.java:60)
api_1 | at io.micronaut.http.context.ServerRequestTracingPublisher$1$$Lambda$636.0000000084166AD0.run(Unknown Source)
api_1 | at io.micronaut.http.context.ServerRequestContext.with(ServerRequestContext.java:52)
api_1 | at io.micronaut.http.context.ServerRequestTracingPublisher$1.onNext(ServerRequestTracingPublisher.java:60)
api_1 | at io.micronaut.http.context.ServerRequestTracingPublisher$1.onNext(ServerRequestTracingPublisher.java:52)
api_1 | at io.reactivex.internal.util.HalfSerializer.onNext(HalfSerializer.java:45)
api_1 | at io.reactivex.internal.subscribers.StrictSubscriber.onNext(StrictSubscriber.java:97)
api_1 | at io.micronaut.reactive.rxjava2.InstrumentedSubscriber.lambda$onNext$0(InstrumentedSubscriber.java:80)
api_1 | at io.micronaut.reactive.rxjava2.InstrumentedSubscriber$$Lambda$635.0000000084161B60.run(Unknown Source)
api_1 | at io.micronaut.reactive.rxjava2.InstrumentedSubscriber.onNext(InstrumentedSubscriber.java:84)
api_1 | at io.reactivex.internal.operators.flowable.FlowableSwitchIfEmpty$SwitchIfEmptySubscriber.onNext(FlowableSwitchIfEmpty.java:59)
api_1 | at io.micronaut.reactive.rxjava2.InstrumentedSubscriber.lambda$onNext$0(InstrumentedSubscriber.java:80)
api_1 | at io.micronaut.reactive.rxjava2.InstrumentedSubscriber$$Lambda$635.0000000084161B60.run(Unknown Source)
api_1 | at io.micronaut.reactive.rxjava2.InstrumentedSubscriber.onNext(InstrumentedSubscriber.java:84)
api_1 | at io.reactivex.internal.operators.flowable.FlowableMap$MapSubscriber.onNext(FlowableMap.java:68)
api_1 | at io.micronaut.reactive.rxjava2.InstrumentedSubscriber.lambda$onNext$0(InstrumentedSubscriber.java:80)
api_1 | at io.micronaut.reactive.rxjava2.InstrumentedSubscriber$$Lambda$635.0000000084161B60.run(Unknown Source)
api_1 | at io.micronaut.reactive.rxjava2.InstrumentedSubscriber.onNext(InstrumentedSubscriber.java:84)
api_1 | at io.reactivex.internal.operators.flowable.FlowableCreate$NoOverflowBaseAsyncEmitter.onNext(FlowableCreate.java:403)
api_1 | at io.micronaut.http.server.netty.RoutingInBoundHandler.lambda$buildResultEmitter$17(RoutingInBoundHandler.java:1422)
api_1 | at io.micronaut.http.server.netty.RoutingInBoundHandler$$Lambda$607.00000000B80AA660.subscribe(Unknown Source)
api_1 | at io.reactivex.internal.operators.flowable.FlowableCreate.subscribeActual(FlowableCreate.java:71)
api_1 | at io.reactivex.Flowable.subscribe(Flowable.java:14918)
api_1 | at io.reactivex.Flowable.subscribe(Flowable.java:14865)
api_1 | at io.micronaut.reactive.rxjava2.RxInstrumentedFlowable.subscribeActual(RxInstrumentedFlowable.java:68)
api_1 | at io.reactivex.Flowable.subscribe(Flowable.java:14918)
api_1 | at io.reactivex.internal.operators.flowable.FlowableMap.subscribeActual(FlowableMap.java:37)
api_1 | at io.reactivex.Flowable.subscribe(Flowable.java:14918)
api_1 | at io.reactivex.Flowable.subscribe(Flowable.java:14865)
api_1 | at io.micronaut.reactive.rxjava2.RxInstrumentedFlowable.subscribeActual(RxInstrumentedFlowable.java:68)
api_1 | at io.reactivex.Flowable.subscribe(Flowable.java:14918)
api_1 | at io.reactivex.internal.operators.flowable.FlowableSwitchIfEmpty.subscribeActual(FlowableSwitchIfEmpty.java:32)
api_1 | at io.reactivex.Flowable.subscribe(Flowable.java:14918)
api_1 | at io.reactivex.Flowable.subscribe(Flowable.java:14865)
api_1 | at io.micronaut.reactive.rxjava2.RxInstrumentedFlowable.subscribeActual(RxInstrumentedFlowable.java:68)
api_1 | at io.reactivex.Flowable.subscribe(Flowable.java:14918)
api_1 | at io.reactivex.Flowable.subscribe(Flowable.java:14868)
api_1 | at io.micronaut.http.context.ServerRequestTracingPublisher.lambda$subscribe$0(ServerRequestTracingPublisher.java:52)
api_1 | at io.micronaut.http.context.ServerRequestTracingPublisher$$Lambda$620.0000000084013F10.run(Unknown Source)
api_1 | at io.micronaut.http.context.ServerRequestContext.with(ServerRequestContext.java:52)
api_1 | at io.micronaut.http.context.ServerRequestTracingPublisher.subscribe(ServerRequestTracingPublisher.java:52)
api_1 | at io.reactivex.internal.operators.flowable.FlowableFromPublisher.subscribeActual(FlowableFromPublisher.java:29)
api_1 | at io.reactivex.Flowable.subscribe(Flowable.java:14918)
api_1 | at io.reactivex.Flowable.subscribe(Flowable.java:14865)
api_1 | at io.micronaut.reactive.rxjava2.RxInstrumentedFlowable.subscribeActual(RxInstrumentedFlowable.java:68)
api_1 | at io.reactivex.Flowable.subscribe(Flowable.java:14918)
api_1 | at io.reactivex.Flowable.subscribe(Flowable.java:14865)
api_1 | at io.reactivex.internal.operators.flowable.FlowableSubscribeOn$SubscribeOnSubscriber.run(FlowableSubscribeOn.java:82)
api_1 | at io.reactivex.internal.schedulers.ExecutorScheduler$ExecutorWorker$BooleanRunnable.run(ExecutorScheduler.java:288)
api_1 | at io.reactivex.internal.schedulers.ExecutorScheduler$ExecutorWorker.run(ExecutorScheduler.java:253)
api_1 | at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128)
api_1 | at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628)
api_1 | at java.base/java.lang.Thread.run(Thread.java:825)
api_1 | Caused by: com.fasterxml.jackson.databind.JsonMappingException: Could not obtain current Hibernate Session; nested exception is org.hibernate.HibernateException: No Session found for current thread (through reference chain: test.Laboratory["attached"])
api_1 | at com.fasterxml.jackson.databind.JsonMappingException.wrapWithPath(JsonMappingException.java:394)
api_1 | at com.fasterxml.jackson.databind.JsonMappingException.wrapWithPath(JsonMappingException.java:353)
api_1 | at com.fasterxml.jackson.databind.ser.std.StdSerializer.wrapAndThrow(StdSerializer.java:316)
api_1 | at com.fasterxml.jackson.databind.ser.std.BeanSerializerBase.serializeFields(BeanSerializerBase.java:727)
api_1 | at com.fasterxml.jackson.databind.ser.BeanSerializer.serialize(BeanSerializer.java:155)
api_1 | at com.fasterxml.jackson.databind.ser.DefaultSerializerProvider._serialize(DefaultSerializerProvider.java:480)
api_1 | at com.fasterxml.jackson.databind.ser.DefaultSerializerProvider.serializeValue(DefaultSerializerProvider.java:319)
api_1 | at com.fasterxml.jackson.databind.ObjectMapper._configAndWriteValue(ObjectMapper.java:3906)
api_1 | at com.fasterxml.jackson.databind.ObjectMapper.writeValueAsBytes(ObjectMapper.java:3244)
api_1 | at io.micronaut.jackson.codec.JsonMediaTypeCodec.encode(JsonMediaTypeCodec.java:173)
api_1 | ... 79 common frames omitted
api_1 | Caused by: org.springframework.dao.DataAccessResourceFailureException: Could not obtain current Hibernate Session; nested exception is org.hibernate.HibernateException: No Session found for current thread
api_1 | at org.grails.orm.hibernate.GrailsHibernateTemplate.getSession(GrailsHibernateTemplate.java:335)
api_1 | at org.grails.orm.hibernate.GrailsHibernateTemplate.doExecute(GrailsHibernateTemplate.java:284)
api_1 | at org.grails.orm.hibernate.GrailsHibernateTemplate.contains(GrailsHibernateTemplate.java:405)
api_1 | at org.grails.orm.hibernate.AbstractHibernateGormInstanceApi.isAttached(AbstractHibernateGormInstanceApi.groovy:220)
api_1 | at org.grails.datastore.gorm.GormEntity$Trait$Helper.isAttached(GormEntity.groovy:176)
api_1 | at org.grails.datastore.gorm.GormEntity$Trait$Helper$isAttached$0.call(Unknown Source)
api_1 | at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:47)
api_1 | at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:115)
api_1 | at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:127)
api_1 | at test.Laboratory.isAttached(Laboratory.groovy)
api_1 | at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
api_1 | at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
api_1 | at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
api_1 | at java.base/java.lang.reflect.Method.invoke(Method.java:566)
api_1 | at com.fasterxml.jackson.databind.ser.BeanPropertyWriter.serializeAsField(BeanPropertyWriter.java:688)
api_1 | at com.fasterxml.jackson.databind.ser.std.BeanSerializerBase.serializeFields(BeanSerializerBase.java:719)
api_1 | ... 85 common frames omitted
api_1 | Caused by: org.hibernate.HibernateException: No Session found for current thread
api_1 | at org.grails.orm.hibernate.GrailsSessionContext.currentSession(GrailsSessionContext.java:112)
api_1 | at org.hibernate.internal.SessionFactoryImpl.getCurrentSession(SessionFactoryImpl.java:495)
api_1 | at org.grails.orm.hibernate.GrailsHibernateTemplate.getSession(GrailsHibernateTemplate.java:333)
api_1 | ... 100 common frames omitted
Я уже пытался использовать Laboratory.withNewSession{...}
, но не работал ...
Создана проблема для этого : https://github.com/micronaut-projects/micronaut-groovy/issues/34
Это репо, содержащее полный пример: https://github.com/mpccolorado/micronaut-gorm-standalone