【问题标题】:DB callbacks like PreUpdate, PreInsert with Spring data jpa and QueryDSL数据库回调,如 PreUpdate、PreInsert with Spring data jpa 和 QueryDSL
【发布时间】:2018-06-15 06:17:32
【问题描述】:

我们使用spring data jpa(spring boot 1.5)和queryDSLMysql DB进行交互。我正在尝试 **intercept 所有数据库调用,如 insert 和 update** 来执行一些操作,如加密/解密。 我尝试像preUpdate 一样实现JPA callbacks,但是当使用queryDSL 实现数据库查询时,它们都没有被调用。 另一方面,当我使用像保存这样的 CrudRepository 方法时,JPA 回调起作用。

@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
    }
}

查询DSL调用

@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 代码

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

在我们的应用程序中,我们使用 QueryDSL、本机查询和 CrudRepository 方法,并希望在集中位置拦截所有数据库调用。 这可以以任何方式实现吗?

【问题讨论】:

  • 问题在于,QueryDSL 正在调用 EntityManager.executeUpdate,并且此方法绕过了持久性上下文以及 EntityListeners。如果要拦截对数据库的所有调用,则必须实现自己的 JDBC 包装器。

标签: hibernate spring-data-jpa querydsl


【解决方案1】:

没有一种适合所有人的解决方案。使用 QueryDSL,您将不会获得回调和实体侦听器的处理程序,因为执行发生在持久性上下文之外。第一行 jpa 回调状态:

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

简单的方法是在帮助类中编写您想要的操作(加密/解密),并将包装器写入 JPAQueryFactory,覆盖所需的事件方法以在事件执行之前拦截您的操作。您可以从回调和/或实体侦听器方法调用相同的辅助类。

这同样适用于您的原生 SQL DAO,为它编写一个包装器。

【讨论】:

    猜你喜欢
    • 2012-11-09
    • 2020-06-16
    • 2016-02-17
    • 2023-03-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-03-29
    • 2020-08-18
    相关资源
    最近更新 更多