そう、
私の Quarkus プロジェクト (v2.2.2) には、次のコア機能があります。
- 反乱を伴うリアクティブなpostgresqlデータベース
- リポジトリをモックしないテスト用の h2 データベース
テストを作成しているときに、quarkus の起動中にエラーが発生しました (エラーの内容は忘れました) が、問題を回避するために名前付きデータソースに切り替えることを推奨するページがいくつかありました。これは当時うまくいったようで、モックリポジトリのテストに合格しました。
少し早送りして、データベースを使用するテストを試みました。私は今、このエラーが発生しています:
java.lang.NullPointerException: Cannot invoke "org.hibernate.reactive.mutiny.Mutiny$Session.createQuery(String)" because "em" is null
at io.quarkus.hibernate.reactive.panache.common.runtime.CommonPanacheQueryImpl.createBaseQuery(CommonPanacheQueryImpl.java:307)
at io.quarkus.hibernate.reactive.panache.common.runtime.CommonPanacheQueryImpl.createQuery(CommonPanacheQueryImpl.java:255)
at io.quarkus.hibernate.reactive.panache.common.runtime.CommonPanacheQueryImpl.lambda$list$6(CommonPanacheQueryImpl.java:221)
at io.smallrye.context.impl.wrappers.SlowContextualFunction.apply(SlowContextualFunction.java:21)
at io.smallrye.mutiny.operators.uni.UniOnItemTransformToUni$UniOnItemTransformToUniProcessor.performInnerSubscription(UniOnItemTransformToUni.java:68)
at io.smallrye.mutiny.operators.uni.UniOnItemTransformToUni$UniOnItemTransformToUniProcessor.onItem(UniOnItemTransformToUni.java:57)
私のapplication.yml(customers名前付きデータソースである):
quarkus:
datasource:
customers:
db-kind: h2
jdbc: false
reactive:
url: h2:file:~/testdb
max-size: 20
私のテスト:
@QuarkusTest
public class CustomerControllerTest {
private static final String BASE_URL = "/my-url";
@Test
public void testBasicCreation() {
final Response response = given()
.when()
.body("{\"a\":3}")
.post(BASE_URL)
.then()
.extract().response();
assertEquals(200, response.getStatusCode(), () -> "Got: " + response.prettyPrint());
assertEquals("", response.getBody().as(String.class));
}
}
私のコントローラの最初のステップは、このリポジトリを使用することです:
@ApplicationScoped
public class MyCustRepo implements io.quarkus.hibernate.reactive.panache.PanacheRepository<MyCust> {
}
そして私のエンティティ:
@Entity(name = "cust_entries")
@Data
@PersistenceUnit("customers")
public class MyCust {
@Id @GeneratedValue(strategy = GenerationType.IDENTITY)
Long id;
@Column(name = "val")
Boolean val;
}
私が見つけたものから@persistenceUnit、エンティティ オブジェクトは適切なデータソースに関連付けられるはずでした。ただし、Mutiny$Session が null のようです。私は何かを逃していますか?
更新 1
Quarkus v 2.3.0 CR1 で
<properties>
<compiler-plugin.version>3.8.1</compiler-plugin.version>
<lombok-mapstruct-binding.version>0.2.0</lombok-mapstruct-binding.version>
<maven.compiler.parameters>true</maven.compiler.parameters>
<maven.compiler.source>11</maven.compiler.source>
<maven.compiler.target>11</maven.compiler.target>
<org.mapstruct.version>1.5.0.Beta1</org.mapstruct.version>
<org.projectlombok.version>1.18.20</org.projectlombok.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<quarkus.platform.artifact-id>quarkus-bom</quarkus.platform.artifact-id>
<quarkus.platform.group-id>io.quarkus.platform</quarkus.platform.group-id>
<quarkus.platform.version>2.3.0.CR1</quarkus.platform.version>
<surefire-plugin.version>3.0.0-M5</surefire-plugin.version>
</properties>
完全な依存関係ツリーはこちら: https://www.codepile.net/pile/8jQeJ3j2
シナリオ 1: デフォルトのデータ ソース (PersistenceUnit アノテーションがなく、application.yaml にデータ ソースの名前がない)
テストを実行すると、次のエラーが発生します。
java.lang.RuntimeException: java.lang.RuntimeException: Failed to start quarkus
Caused by: java.lang.RuntimeException: Failed to start quarkus
Caused by: java.lang.RuntimeException: javax.persistence.PersistenceException: Unable to build EntityManagerFactory
Caused by: javax.persistence.PersistenceException: Unable to build EntityManagerFactory
Caused by: java.lang.IllegalStateException: No pool has been defined for persistence unit default-reactive
シナリオ 2: 名前付きデータ ソースを使用するように設定すると、次のようになります。
my.project.customer.conrtoller.CustomerControllerTest.testBasicCreation Time elapsed: 2.12 s <<< FAILURE!
org.opentest4j.AssertionFailedError:
Got: {
"details": "Error id 083dd288-ddff-463b-bfd1-dafdbbf13c98-1, java.lang.NullPointerException: Cannot invoke \"org.hibernate.reactive.mutiny.Mutiny$Session.createQuery(String)\" because \"em\" is null",
"stack": "java.lang.NullPointerException: Cannot invoke \"org.hibernate.reactive.mutiny.Mutiny$Session.createQuery(String)\" because \"em\" is null\r\n\tat io.quarkus.hibernate.reactive.panache.common.runtime.CommonPanacheQueryImpl.createBaseQuery(CommonPanacheQueryImpl.java:307)\r\n\tat io.quarkus.hibernate.reactive.panache.common.runtime.CommonPanacheQueryImpl.createQuery(CommonPanacheQueryImpl.java:255)\r\n\tat io.quarkus.hibernate.reactive.panache.common.runtime.CommonPanacheQueryImpl.lambda$list$6(CommonPanacheQueryImpl.java:221)\r\n\tat io.smallrye.context.impl.wrappers.SlowContextualFunction.apply(SlowContextualFunction.java:21)\r\n\tat io.smallrye.mutiny.operators.uni.UniOnItemTransformToUni$UniOnItemTransformToUniProcessor.performInnerSubscription(UniOnItemTransformToUni.java:68)\r\n\tat io.smallrye.mutiny.operators.uni.UniOnItemTransformToUni$UniOnItemTransformToUniProcessor.onItem(UniOnItemTransformToUni.java:57)\r\n\tat io.smallrye.mutiny.operators.uni.builders.UniCreateFromKnownItem$KnownItemSubscription.forward(UniCreateFromKnownItem.java:38)\r\n\tat io.smallrye.mutiny.operators.uni.builders.UniCreateFromKnownItem$KnownItemSubscription.access$100(UniCreateFromKnownItem.java:26)\r\n\tat io.smallrye.mutiny.operators.uni.builders.UniCreateFromKnownItem.subscribe(UniCreateFromKnownItem.java:23)\r\n\tat io.smallrye.mutiny.operators.AbstractUni.subscribe(AbstractUni.java:36)\r\n\tat io.smallrye.mutiny.operators.uni.UniOnItemTransformToUni.subscribe(UniOnItemTransformToUni.java:25)\r\n\tat io.smallrye.mutiny.operators.AbstractUni.subscribe(AbstractUni.java:36)\r\n\tat io.smallrye.mutiny.converters.uni.UniToMultiPublisher$UniToMultiSubscription.request(UniToMultiPublisher.java:58)\r\n\tat io.smallrye.mutiny.operators.multi.MultiFlatMapOp$FlatMapMainSubscriber.onSubscribe(MultiFlatMapOp.java:163)\r\n\tat io.smallrye.mutiny.converters.uni.UniToMultiPublisher.subscribe(UniToMultiPublisher.java:26)\r\n\tat io.smallrye.mutiny.groups.MultiCreate$1.subscribe(MultiCreate.java:156)\r\n\tat io.smallrye.mutiny.operators.multi.MultiFlatMapOp.subscribe(MultiFlatMapOp.java:56)\r\n\tat io.smallrye.mutiny.groups.MultiSubscribe.withSubscriber(MultiSubscribe.java:69)\r\n\tat io.smallrye.mutiny.operators.multi.MultiSelectWhereOp.subscribe(MultiSelectWhereOp.java:30)\r\n\tat io.smallrye.mutiny.operators.AbstractMulti.subscribe(AbstractMulti.java:40)\r\n\tat io.smallrye.mutiny.operators.multi.MultiFlatMapOp.subscribe(MultiFlatMapOp.java:56)\r\n\tat io.smallrye.mutiny.operators.AbstractMulti.subscribe(AbstractMulti.java:40)\r\n\tat io.smallrye.mutiny.operators.uni.builders.UniCreateFromPublisher$PublisherSubscriber.forward(UniCreateFromPublisher.java:42)\r\n\tat io.smallrye.mutiny.operators.uni.builders.UniCreateFromPublisher$PublisherSubscriber.access$100(UniCreateFromPublisher.java:30)\r\n\tat io.smallrye.mutiny.operators.uni.builders.UniCreateFromPublisher.subscribe(UniCreateFromPublisher.java:26)\r\n\tat io.smallrye.mutiny.operators.AbstractUni.subscribe(AbstractUni.java:36)\r\n\tat io.smallrye.mutiny.operators.uni.UniOnItemTransform.subscribe(UniOnItemTransform.java:22)\r\n\tat io.smallrye.mutiny.operators.AbstractUni.subscribe(AbstractUni.java:36)\r\n\tat io.smallrye.mutiny.operators.uni.UniOnItemTransform.subscribe(UniOnItemTransform.java:22)\r\n\tat io.smallrye.mutiny.operators.AbstractUni.subscribe(AbstractUni.java:36)\r\n\tat io.smallrye.mutiny.operators.uni.UniOnItemTransformToUni.subscribe(UniOnItemTransformToUni.java:25)\r\n\tat io.smallrye.mutiny.operators.AbstractUni.subscribe(AbstractUni.java:36)\r\n\tat io.smallrye.mutiny.operators.uni.UniOnItemTransform.subscribe(UniOnItemTransform.java:22)\r\n\tat io.smallrye.mutiny.operators.AbstractUni.subscribe(AbstractUni.java:36)\r\n\tat io.smallrye.mutiny.operators.uni.UniOnItemTransform.subscribe(UniOnItemTransform.java:22)\r\n\tat io.smallrye.mutiny.operators.AbstractUni.subscribe(AbstractUni.java:36)\r\n\tat io.smallrye.mutiny.groups.UniSubscribe.withSubscriber(UniSubscribe.java:50)\r\n\tat io.smallrye.mutiny.groups.UniSubscribe.with(UniSubscribe.java:90)\r\n\tat org.jboss.resteasy.reactive.server.handlers.UniResponseHandler.handle(UniResponseHandler.java:17)\r\n\tat org.jboss.resteasy.reactive.server.handlers.UniResponseHandler.handle(UniResponseHandler.java:8)\r\n\tat org.jboss.resteasy.reactive.common.core.AbstractResteasyReactiveContext.run(AbstractResteasyReactiveContext.java:141)\r\n\tat io.vertx.core.impl.EventLoopContext.execute(EventLoopContext.java:81)\r\n\tat io.vertx.core.impl.ContextImpl.execute(ContextImpl.java:260)\r\n\tat io.vertx.core.impl.EventLoopContext.execute(EventLoopContext.java:22)\r\n\tat org.jboss.resteasy.reactive.server.vertx.VertxResteasyReactiveRequestContext$1.execute(VertxResteasyReactiveRequestContext.java:69)\r\n\tat org.jboss.resteasy.reactive.common.core.AbstractResteasyReactiveContext.resume(AbstractResteasyReactiveContext.java:82)\r\n\tat org.jboss.resteasy.reactive.common.core.AbstractResteasyReactiveContext.resume(AbstractResteasyReactiveContext.java:50)\r\n\tat org.jboss.resteasy.reactive.server.handlers.InputHandler$InputListener.done(InputHandler.java:84)\r\n\tat org.jboss.resteasy.reactive.server.vertx.VertxResteasyReactiveRequestContext$5.handle(VertxResteasyReactiveRequestContext.java:260)\r\n\tat org.jboss.resteasy.reactive.server.vertx.VertxResteasyReactiveRequestContext$5.handle(VertxResteasyReactiveRequestContext.java:254)\r\n\tat io.vertx.core.impl.AbstractContext.dispatch(AbstractContext.java:100)\r\n\tat io.vertx.core.impl.AbstractContext.dispatch(AbstractContext.java:63)\r\n\tat io.vertx.core.http.impl.HttpEventHandler.handleEnd(HttpEventHandler.java:76)\r\n\tat io.vertx.core.http.impl.Http1xServerRequest.onEnd(Http1xServerRequest.java:565)\r\n\tat io.vertx.core.http.impl.Http1xServerRequest.lambda$pendingQueue$1(Http1xServerRequest.java:127)\r\n\tat io.vertx.core.streams.impl.InboundBuffer.handleEvent(InboundBuffer.java:240)\r\n\tat io.vertx.core.streams.impl.InboundBuffer.write(InboundBuffer.java:130)\r\n\tat io.vertx.core.http.impl.Http1xServerRequest.handleEnd(Http1xServerRequest.java:546)\r\n\tat io.vertx.core.impl.EventLoopContext.execute(EventLoopContext.java:71)\r\n\tat io.vertx.core.impl.DuplicatedContext.execute(DuplicatedContext.java:163)\r\n\tat io.vertx.core.http.impl.Http1xServerConnection.onEnd(Http1xServerConnection.java:189)\r\n\tat io.vertx.core.http.impl.Http1xServerConnection.onContent(Http1xServerConnection.java:179)\r\n\tat io.vertx.core.http.impl.Http1xServerConnection.handleOther(Http1xServerConnection.java:159)\r\n\tat io.vertx.core.http.impl.Http1xServerConnection.handleMessage(Http1xServerConnection.java:147)\r\n\tat io.vertx.core.net.impl.ConnectionBase.read(ConnectionBase.java:155)\r\n\tat io.vertx.core.net.impl.VertxHandler.channelRead(VertxHandler.java:154)\r\n\tat io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:379)\r\n\tat io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:365)\r\n\tat io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:357)\r\n\tat io.netty.channel.ChannelInboundHandlerAdapter.channelRead(ChannelInboundHandlerAdapter.java:93)\r\n\tat io.netty.handler.codec.http.websocketx.extensions.WebSocketServerExtensionHandler.channelRead(WebSocketServerExtensionHandler.java:99)\r\n\tat io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:379)\r\n\tat io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:365)\r\n\tat io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:357)\r\n\tat io.netty.handler.timeout.IdleStateHandler.channelRead(IdleStateHandler.java:286)\r\n\tat io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:379)\r\n\tat io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:365)\r\n\tat io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:357)\r\n\tat io.netty.handler.codec.ByteToMessageDecoder.fireChannelRead(ByteToMessageDecoder.java:324)\r\n\tat io.netty.handler.codec.ByteToMessageDecoder.channelRead(ByteToMessageDecoder.java:296)\r\n\tat io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:379)\r\n\tat io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:365)\r\n\tat io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:357)\r\n\tat io.vertx.core.http.impl.Http1xOrH2CHandler.end(Http1xOrH2CHandler.java:61)\r\n\tat io.vertx.core.http.impl.Http1xOrH2CHandler.channelRead(Http1xOrH2CHandler.java:38)\r\n\tat io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:379)\r\n\tat io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:365)\r\n\tat io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:357)\r\n\tat io.netty.handler.timeout.IdleStateHandler.channelRead(IdleStateHandler.java:286)\r\n\tat io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:379)\r\n\tat io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:365)\r\n\tat io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:357)\r\n\tat io.netty.channel.DefaultChannelPipeline$HeadContext.channelRead(DefaultChannelPipeline.java:1410)\r\n\tat io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:379)\r\n\tat io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:365)\r\n\tat io.netty.channel.DefaultChannelPipeline.fireChannelRead(DefaultChannelPipeline.java:919)\r\n\tat io.netty.channel.nio.AbstractNioByteChannel$NioByteUnsafe.read(AbstractNioByteChannel.java:166)\r\n\tat io.netty.channel.nio.NioEventLoop.processSelectedKey(NioEventLoop.java:719)\r\n\tat io.netty.channel.nio.NioEventLoop.processSelectedKeysOptimized(NioEventLoop.java:655)\r\n\tat io.netty.channel.nio.NioEventLoop.processSelectedKeys(NioEventLoop.java:581)\r\n\tat io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:493)\r\n\tat io.netty.util.concurrent.SingleThreadEventExecutor$4.run(SingleThreadEventExecutor.java:986)\r\n\tat io.netty.util.internal.ThreadExecutorMap$2.run(ThreadExecutorMap.java:74)\r\n\tat io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30)\r\n\tat java.base/java.lang.Thread.run(Thread.java:832)"
} ==> expected: <200> but was: <500>
at my.project.customer.conrtoller.CustomerControllerTest.testBasicCreation(CustomerControllerTest.java:35)