Data not saved in db when the time @PostPersist got called

1.3k views Asked by At

I need to send a request to other microService once the object got created in the database. I only send the object id so other microService needs to call the db again for the info with bunch of other stuff.

But, when the other microService try to lookup for the record using the received id it cannot find the saved record in the database.

I tried debug seems like record does not persist even though @postPersist got called. It will be saved after @PostPersist got executed.

Has anyone could give a workaround for this. I really need to query the database again as this is a custom requirement. I use mysql and spring boot

public class EmployeeListener {

    @PostPersist
    public void sendData(Employee employee){
        Long id = employee.getEmployeeId();
        RestTemplate restTemplate = new RestTemplate();
        restTemplate.exchange("http://localhost:8081/service/employee"+id, HttpMethod.POST, null, String.class);

    }

}


@Entity
@EntityListeners(EmployeeListener.class)
public class Employee {
       //
}
2

There are 2 answers

6
AudioBubble On

@PostPersist annotated method is called within the same transaction and the default flash mode is AUTO, that's why you don't see the record in the database. You need to force a flush:

@Component
public class EmployeeListener {

    @PersistenceContext
    private EntityManager entityManager;

    @PostPersist
    public void sendData(Employee employee){
        // Send it to database
        entityManager.flush();
        Long id = employee.getEmployeeId();
        RestTemplate restTemplate = new RestTemplate();
        restTemplate.exchange("http://localhost:8081/service/employee"+id, HttpMethod.POST, null, String.class);

    }

}

Notice that EmployeeListener needs to be a Spring managed bean.

0
Jens Schauder On

The problem is that JPA lifecycle events happen in the same transaction as your save operation, but the lookup, since it happens with a different server must only happen after your transaction is closed.

I therefore recommend the following setup: Gather the ids that need informing in a Collection and then when the transaction is completed send the data.

If you want to have the send operation and save operation in one method, the [TransactionTemplate][1] might be nicer to use than transaction management by annotation.

You also might consider Domain Events. Note that they trigger only when save is actually called. The benefit of these events is that they get published using a ApplicationEventPublisher for which listeners are Spring Beans so you may inject whatever bean you find helpful. They still need a way to break out of the transaction as described above