Vert.x Web , GraphQL , Hibernate Reactive



我将用Vert.x web和GraphQL编写一个Api
我已经用Hibernate reactive连接了数据库

public void start(final Promise<Void> startPromise)
{
try
{
vertx.executeBlocking(e ->
{
try
{
hibernateConfig();
e.complete();
}
catch (Exception exception)
{
e.fail(exception.getCause());
}
}).onComplete(event ->
{
try
{
runServer(startPromise);
}
catch (Exception e)
{
throw new RuntimeException(e);
}
}).onFailure(Throwable::printStackTrace);
}
catch (Exception e)
{
e.printStackTrace();
}
}
private void runServer(final Promise<Void> startPromise) throws Exception
{
final HttpServer httpServer = vertx.createHttpServer();
final Router router = Router.router(vertx);
router.route().handler(BodyHandler.create());
router.post("/graphql").handler(super::graphqlHandler);
// register `/graphiql` endpoint for the GraphiQL UI
final GraphiQLHandlerOptions graphiqlOptions = new GraphiQLHandlerOptions().setEnabled(true);
router.route("/graphiql/*").handler(GraphiQLHandler.create(graphiqlOptions));
final URL resource = getClass().getResource("/static");
if (resource != null) router.route("/static/*").handler(StaticHandler.create(resource.getFile()));
else throw new Exception("Cannot set static");
httpServer.requestHandler(router).listen(PORT , "localhost" , event ->
{
if (event.succeeded())
{
System.out.printf("Server run on port %d!n" , PORT);
startPromise.complete();
}
else
{
System.out.println("Error run server!");
startPromise.fail(event.cause());
}
});
}
private void hibernateConfig()
{
Uni.createFrom().deferred(Unchecked.supplier(() ->
{
final Configuration configuration = new Configuration().setProperties(getHibernateProperties());
final Set<Class<?>> entitiesClasses = getEntitiesClasses();
if (entitiesClasses != null)
{
for (final Class<?> entity : entitiesClasses) configuration.addAnnotatedClass(entity);
}
else logger.error("Cannot found entities");
final StandardServiceRegistryBuilder builder = new ReactiveServiceRegistryBuilder()
.addService(Server.class , this)
.applySettings(configuration.getProperties());
final StandardServiceRegistry registry = builder.build();
sessionFactory = configuration.buildSessionFactory(registry).unwrap(Mutiny.SessionFactory.class);
if (!sessionFactory.isOpen()) throw new RuntimeException("Session is close!");
logger.info("✅ Hibernate Reactive is ready");
return Uni.createFrom().voidItem();
})).convert().toCompletableFuture().join();
}
private Properties getHibernateProperties()
{
final Properties properties = new Properties();
properties.setProperty(Environment.DRIVER , "org.mysql.jdbc.DRIVER");
properties.setProperty(Environment.URL , "jdbc:mysql://localhost:3306/DBNAME");
properties.setProperty(Environment.USER , "USENAME");
properties.setProperty(Environment.PASS , "PASSWORD");
properties.setProperty(Environment.DIALECT , "org.hibernate.dialect.MySQL55Dialect");
properties.setProperty(Environment.HBM2DDL_DATABASE_ACTION , "create");
properties.setProperty(Environment.SHOW_SQL , "false");
properties.setProperty(Environment.POOL_SIZE , "10");
return properties;
}

到目前为止,它没有给出任何错误,并创建了实体

当我想插入时会出现错误

public Future<UsersDto> addUserTest(final DataFetchingEnvironment environment)
{
return Future.future(event ->
{
final AddUsersDto addUsersDto = Dto.mapped(environment.getArguments() , "user" , AddUsersDto.class);
final Users user = UsersMapper.toUsers(addUsersDto);
try
{
vertx.executeBlocking(e ->
{
try
{
sessionFactory.withTransaction(
(session , transaction) ->
session.persist(user)
.chain(session::flush)
)
.invoke(() -> e.complete(user))
.onFailure()
.invoke(e::fail)
.await()
.indefinitely();
}
catch (Exception exception)
{
exception.printStackTrace();
e.fail(exception.getCause());
}
})
.onComplete(e -> event.complete(UsersMapper.toUsersDto((Users) e.result())))
.onFailure(e -> event.fail(e.getCause()));
}
catch (Exception e)
{
e.printStackTrace();
event.complete(UsersDto.builder().build());
}
});
}

错误:

sessionFactory.withTransaction(
(session , transaction) ->
session.persist(user)
.chain(session::flush)
)
.invoke(() -> e.complete(user))
.onFailure()
.invoke(e::fail)
.await()
.indefinitely(); // This line gives an error

错误文本:

java.lang.IllegalStateException:HR000068:此方法应仅从Vert.x EventLoop线程调用;当前正在线程'vert.x-worker-thread-1'上运行

如果有人知道的问题,请帮助我

问题是您正在运行工作线程中的所有内容(使用executeBlocking(。

如果您正在编写响应式代码,则不需要等待结果可用。

代码应该是这样的:

public Future<UsersDto> addUserTest(final DataFetchingEnvironment environment) {
return Future.future(event -> {
final AddUsersDto addUsersDto = Dto.mapped(environment.getArguments() , "user" , AddUsersDto.class);
final Users user = UsersMapper.toUsers(addUsersDto);
sessionFactory
.withTransaction( (session , tx) -> session.persist(user) )
.subscribe().with( event::complete, event::fail )
});
}

您也不需要刷新,因为存在事务。

有一个关于Hibernate Reactive存储库的工作示例

相关内容

  • 没有找到相关文章

最新更新