1

I'm using hibernate and JpaRepository + PostgreSQL. I have the following code which listens to any modifications made to the database.

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));
    }
}

In the method perform, it is where changes made would be updated into a new table. At this point, i wish to also send this "PermitHistory" back to the user via a web socket. This is so that when the user is modifying/viewing the table, on the client side he will be able to receive a prompt that new changes have been made to the fields so he can choose to refresh to display the updates.

I created a new class "PermitUpdates"

public class PermitUpdates {

    @Autowired
    private SimpMessagingTemplate template;

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

I also added a WebSocketConfig class

@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();
    }

}

With this an error occured:

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

What am i doing wrong? How do i let spring create the object for me?

Cherple
  • 725
  • 3
  • 10
  • 24
  • Possible duplicate of [What is a NullPointerException, and how do I fix it?](https://stackoverflow.com/questions/218384/what-is-a-nullpointerexception-and-how-do-i-fix-it) – Selaron Feb 06 '19 at 11:51
  • I understand the null pointer part, but because of how spring and hibernate works, with all the autowiring and stuff, i'm not very sure what's happening in the background.. and how to go about resolving them. – Cherple Feb 07 '19 at 01:33
  • Seemes like your question is related to Spring and Autowiring only, not Hibernate nor PostreSQL nor websockets. As the NPE occurres in your code and not in the deep stack of a framework, it's legit to add this duplication flag, especially because that NPE seemes to be the main concern of the question. – Selaron Feb 07 '19 at 10:00
  • Maybe you could reword your question to focus on why autowiring does not work in that class and how to get a reference to that Spring managed `SimpMessagingTemplate` - plus removing irrelevant tags. – Selaron Feb 07 '19 at 10:03

1 Answers1

2

Line 19 of PermitUpdates is this : this.template.convertAndSend("/changes", permitHistory);? If so template is not injected, because PermitUpdates is not created by Spring (see PermitEntityListener method private void perform(Permit target, Action action) PermitUpdates updates = new PermitUpdates())

You have to let spring create object or inject properties manually.

Tijkijiki
  • 792
  • 7
  • 19
  • Yes that is Line 19. How do i modify my code so it would work? I'm not familiar with spring and i'm not sure how to resolve this. I've added "@Controller" for my PermitUpdates class. How can i call the sendUpdatedPermit method from my PermitEntityListener's "Perform" method? – Cherple Feb 07 '19 at 01:55
  • All samples/examples i see online are teaching how to call it from the client side, but for my case i wish to trigger it from the back-end.. Since the back-end will know when a database change has been made and should then trigger the "sendUpdatedPermit" method to send these information back to the clients. – Cherple Feb 07 '19 at 01:57
  • From dependency injection point of view, assuming that `PermitEntityListener` is crated by spring, you should remove inicialization `PermitUpdates updates = new PermitUpdates()` and let spring to inject instance, f.e. definine `@Autowired private PermitUpdates update;` – Tijkijiki Feb 07 '19 at 21:54