use*_*339 5 postgresql vert.x quarkus hibernate-reactive
我正在尝试将quarkus-hibernate-reactive扩展与quarkus-vertx扩展一起使用,但在保留数据方面遇到问题。我的项目大致如下:
水果资源:
@Inject
EventBus eventBus;
@POST
public Uni<Response> create(Fruit fruit) {
if (fruit == null || fruit.getId() != null) {
throw new WebApplicationException("Id was invalidly set on request.", 422);
}
return eventBus.<Void>request("create-fruit", fruit)
.map(ignore -> Response.ok(fruit).status(201).build());
}
Run Code Online (Sandbox Code Playgroud)
水果服务:
@Inject
FruitRepository fruitRepository;
@ConsumeEvent("create-fruit")
public Uni<Void> createFruit(final Fruit fruit) {
return fruitRepository.create(fruit);
}
Run Code Online (Sandbox Code Playgroud)
水果库:
@Inject
Mutiny.Session mutinySession;
public Uni<Void> create(final Fruit fruit) {
return mutinySession
.persist(fruit)
.chain(mutinySession::flush);
}
Run Code Online (Sandbox Code Playgroud)
我得到的例外是 a java.lang.IllegalStateException: Session/EntityManager is closed,我认为发生在flush(). 我猜我的会话会在某个地方结束,但我不知道在哪里以及如何防止这种情况发生。
完整的示例可以在这里找到: https: //github.com/bamling/quarkus-hibernate-reactive-test
FruitsEndpointTest模拟行为!
好吧,我知道这个答案并不完全是您正在寻找的,但这是迄今为止我找到的唯一可行的解决方案。我将继续寻找一种方法来实现它并具有所有 Hibernate 优点,但这里是一个没有以下内容的解决方案:
@ApplicationScoped
public class FruitRepository {
@Inject
PgPool client;
public Multi<Fruit> findAll() {
return client.query("SELECT id, name FROM known_fruits ORDER BY name ASC").execute()
.onItem().transformToMulti(set -> Multi.createFrom().iterable(set))
.onItem().transform(FruitRepository::map);
}
public Uni<Void> create(final Fruit fruit) {
return client.preparedQuery("INSERT INTO known_fruits (id, name) VALUES ($1, $2)")
.execute(Tuple.tuple().addInteger(fruit.getId()).addString(fruit.getName()))
.chain(e -> Uni.createFrom().voidItem());
}
public static Fruit map(Row row) {
Fruit fruit = new Fruit();
fruit.setId(row.getInteger("id"));
fruit.setName(row.getString("name"));
return fruit;
}
}
Run Code Online (Sandbox Code Playgroud)
它有效,它是反应性的,但它也意味着手动管理对象关系。不理想。
更新:
这是一个使用 Hibernate 的工作示例。但是(!)它远非完美。虽然它更接近回答你的问题,但我总是更喜欢使用上面的例子而不是这个。会议应该关闭。我也想为 findAll 方法执行“withSession()”,但这会返回 Uni,而我们需要 Multi。尝试使用资源不起作用,因为这将在读取 Multi 之前关闭会话。因此,不要使用此代码,但也许它会帮助其他人提出更好的答案:
@ApplicationScoped
public class FruitRepository {
private final Mutiny.SessionFactory sessionFactory;
public FruitRepository(EntityManagerFactory entityManagerFactory) {
this.sessionFactory = entityManagerFactory.unwrap(Mutiny.SessionFactory.class);
}
public Multi<Fruit> findAll() {
Mutiny.Session session = sessionFactory.openSession();
return session.createNamedQuery("Fruits.findAll", Fruit.class).getResults();
}
public Uni<Void> create(final Fruit fruit) {
return sessionFactory.withSession(
session -> session.persist(fruit)
.chain(e -> Uni.createFrom().voidItem())
);
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
2982 次 |
| 最近记录: |