0
votes

We are using spring data jpa (spring boot 1.5) and queryDSL to interact with Mysql DB. I am trying to **intercept all DB calls like insert and update** to do some operations like encryption/decryption. I tried to implement JPA callbacks like preUpdate but none of them are being called when a DB query implemented using queryDSL. On the other hand, JPA callbacks works when I use CrudRepository methods like save.

@Entity
@Table(name = "APPLICATION")
public class Application implements Serializable {

    @Id
    @Column(name = "ID", unique = true)
    private Long id;

    @Column(name = "PAN", insertable = false)
    private String pan;

    @PreUpdate
    void preUpdate() throws IOException, HttpException {
        //logic to encrypt before update is called
    }
}

QueryDSL call

@Autowired
private JPAQueryFactory queryFactory;

@Transactional
@Override
public void updatePanById(String pan, Long id) {
    QApplication application = QApplication.application;
    queryFactory.update(application)
            .set(application.pan, pan)
            .where(loan.id.eq(id))
            .execute();
}

JPA code

Application application = applicationRepository.findById(id);
application.setPan("ABC");
applicationRepository.save(application);

In our application we are using QueryDSL, native queries and CrudRepository methods and want to intercept all DB calls at centralised place. Is this achievable in any way ?

1
The problem ist, that QueryDSL is calling EntityManager.executeUpdate and this method bypass the Persistence Context and also the EntityListeners. If you want to intercept all calls to the DB you must implement your own JDBC wrapper. - Simon Martinelli

1 Answers

0
votes

There is no one solution that fits all. With QueryDSL, you will not get handler to callbacks & entitylisteners as the execution occurs outside the persistence context. The first line of jpa callback states:

It is often useful for the application to react to certain events that occur inside the **persistence mechanism**

Easy way is write your desired operation (encryption/decryption) in a helper class, and write wrapper to JPAQueryFactory, override desired event(s) method to intercept your operation before event execution. And same helper class you can call from your callback and/or entitylistener methods.

The same applies to your native SQL DAOs, write a wrapper to it.