在Vertx EventBus使用者

时间:2018-04-11 07:31:01

标签: java spring-boot jpa vert.x

我在Vert.x eventbus上创建了一个消费者:

@Autowired
private Vertx vertx;

public void registerConsumer() {
    EventBus eb = vertx.eventBus();

    eb.consumer("action.request", (Message<String> msg) -> {
        handleIncomingRequest(msg);
    });
}

handleIncomingRequest链中,我调用服务从psql数据库中获取实体:

private void handleIncomingRequest(Request request) {
    SystemNode system = systemService
            .getSystemWithHistoryFrom(request.getUuid());

    // All lazily initialized collections unavailable here

    systemService.update(system);
}

在上面的方法中,我尝试对SystemNode对象中的集合执行一些操作。但是,永远不会获取此对象上的延迟初始化集合。我尝试过设置@Fetch(FetchMode.JOIN)FetchType.EAGER。当我检查对象时,我可以看到它是一个持久集,它向我显示以下错误:

  

com.sun.jdi.InvocationException发生了调用方法。

进一步检查显示与此persisent集相关的会话为null,因此调用Hibernate.initialize(system.getSomeCollection())将引发异常。

这两种方法都解决了这个问题,但这不是一个选项,因为如果它不会被使用,那么每次收集太大而无法获取。

在eventbus消费者之外的任何地方调用服务,为我提供了一个可以按需初始化的集合。

我做错了什么?

1 个答案:

答案 0 :(得分:2)

好吧,您应该将传入的请求处理逻辑包装到单个事务方法中,以防止实体在systemService.getSystemWithHistoryFrom()systemService.update()的调用之间分离。像@Transactional public void SystemService.getSystemHistoryDoImportantStuffAndSaveResults()这样的东西。

或者,您可以自定义由systemService.getSystemWithHistoryFrom()执行的查询到JOIN FETCH所有必需的集合,并保持集合在实体本身内延迟获取。但是,将整个业务逻辑包装在事务中会更加安全,因为除了解决问题之外,它还会强制执行事务隔离