【问题标题】:Null pointer exception when trying to convert and send via websocket尝试通过 websocket 转换和发送时出现空指针异常
【发布时间】:2019-02-06 10:33:22
【问题描述】:

我正在使用休眠和 JpaRepository + PostgreSQL。我有以下代码可以监听对数据库所做的任何修改。

public class PermitEntityListener {

    @PrePersist
    public void prePersist(Permit target) {
        perform(target, INSERTED);
    }

    @PreUpdate
    public void preUpdate(Permit target) {
        perform(target, UPDATED);
    }

    @PreRemove
    public void preRemove(Permit target) {
        perform(target, DELETED);
    }

    @Transactional(MANDATORY)
    private void perform(Permit target, Action action) {
        EntityManager entityManager = BeanUtil.getBean(EntityManager.class);
        entityManager.persist(new PermitHistory(target, action));
        //Send permitHistory to client via websocket to update changes
        PermitUpdates updates = new PermitUpdates();
        updates.sendUpdatedPermit(new PermitHistory(target, action));
    }
}

在方法 perform 中,所做的更改将更新到新表中。此时,我还希望通过 Web 套接字将此“PermitHistory”发回给用户。这样当用户在修改/查看表格时,在客户端他将能够收到一个提示,表明已对字段进行了新的更改,因此他可以选择刷新以显示更新。

我创建了一个新类“PermitUpdates”

public class PermitUpdates {

    @Autowired
    private SimpMessagingTemplate template;

    public void sendUpdatedPermit(PermitHistory permitHistory) {
        if (permitHistory != null) {
            this.template.convertAndSend("/changes", permitHistory);
        }
    }
}

我还添加了一个 WebSocketConfig 类

@Configuration
@EnableWebSocketMessageBroker
public class WebSocketConfig implements WebSocketMessageBrokerConfigurer {

    @Override
    public void configureMessageBroker(MessageBrokerRegistry config) {
        config.enableSimpleBroker("/changes");
        config.setApplicationDestinationPrefixes("/app");
    }

    @Override
    public void registerStompEndpoints(StompEndpointRegistry registry) {
        registry.addEndpoint("/gs-guide-websocket").withSockJS();
    }

}

出现错误:

Caused by: java.lang.NullPointerException
    at com.example.historical.websoc.PermitUpdates.sendUpdatedPermit(PermitUpdates.java:19)

我做错了什么?我如何让 spring 为我创建对象?

【问题讨论】:

  • 我了解空指针部分,但由于 spring 和 hibernate 的工作方式以及所有自动装配和东西,我不太确定后台发生了什么......以及如何解决他们。
  • 似乎您的问题仅与 Spring 和 Autowiring 有关,与 Hibernate、PostreSQL 或 websockets 无关。由于 NPE 出现在您的代码中而不是框架的深层堆栈中,因此添加此重复标志是合法的,尤其是因为 NPE 似乎是问题的主要关注点。
  • 也许你可以改写你的问题,把重点放在为什么自动装配在该类中不起作用以及如何获得对 Spring 管理的 SimpMessagingTemplate 的引用 - 加上删除不相关的标签。

标签: spring postgresql hibernate websocket spring-data-jpa


【解决方案1】:

PermitUpdates 的第 19 行是这样的:this.template.convertAndSend("/changes", permitHistory);?如果没有注入模板,因为 PermitUpdates 不是由 Spring 创建的(参见 PermitEntityListener 方法private void perform(Permit target, Action action) PermitUpdates updates = new PermitUpdates())

你必须让 spring 手动创建对象或注入属性。

【讨论】:

  • 是的,这是第 19 行。如何修改我的代码以使其正常工作?我不熟悉spring,我不知道如何解决这个问题。我为我的 PermitUpdates 类添加了“@Controller”。如何从 PermitEntityListener 的“Perform”方法中调用 sendUpdatedPermit 方法?
  • 我在网上看到的所有示例/示例都在教如何从客户端调用它,但就我而言,我希望从后端触发它。因为后端会知道什么时候已进行数据库更改,然后应触发“sendUpdatedPermit”方法将这些信息发送回客户端。
  • 从依赖注入的角度来看,假设PermitEntityListener是spring创建的,你应该去掉初始化PermitUpdates updates = new PermitUpdates(),让spring来注入实例,f.e.定义@Autowired private PermitUpdates update;
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-10-29
  • 2016-04-16
  • 2020-11-13
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多