Spring Data JPA 从入门到精通~@PreUpdate异常场景分析
1、执行save()后,再次save(),@PreUpdate不再触发
2、@Transient字段的变更,不会触发@PreUpdate方法
3、@PreUpdate 不适用加密/解密场景
1、执行save()后,再次save(),@PreUpdate不再触发
实体:
@Entity
@EntityListeners(MyEntityListener.class)
class MyEntity{ ... }
监听器:
class MyEntityListener{@PrePersist@PreUpdatepublic void doSomething(Object entity){ ... }
}
使用Spring Data生成的DAO。代码行为如下:
MyEntity entity = new Entity();
entity = dao.save(entity); // the doSomething() is called here
// change something it the entity and save it again
dao.save(entity); // the doSomething() is NOT called here, checked with breakpoint
第一次save() 触发了doSomething(),修复实体后,第二次save()不再触发doSomething()...
2、@Transient字段的变更,不会触发@PreUpdate方法
JPA 的 @Transient 注解用于表示一个字段不持久化到数据库中
有一个用户实体类,我正在尝试为此进行密码哈希处理。我认为最简单的方法是创建一个用@Transient注释的密码字段,以及一个在对象持久化之前设置的用@PrePersist和@PreUpdate注释的哈希密码字段。
所以我有这样的东西
@Transient
private String password;private String hashedPassword;@PrePersist
@PreUpdate
private void hashPassword() {if(password != null) {hashedPassword = PasswordHasher.hashPassword(password);}
}
当实体持久存在时,此方法效果很好。密码字段仍在调用hashPassword时设置,并计算并存储hashedPassword的值。
但是,更新并非如此-即使在合并实体之前设置了新的password值,该字段在hashPassword之前也为null叫做。为什么是这样?至少在实体存在之前,瞬态场的值是否应该一直存在?
3、@PreUpdate 不适用加密/解密场景
如果仅是简单的单个实体操作,还勉强正确;但是对于一个复杂的聚合,查询了User,然后再查询关联的Company,这样就会触发@PreUpdate,导致User的mobile、cardNO又变成加密状态(关键这时候也没有事务提交动作啊)
@Entity
public class User {/*** 手机号.*/private String mobile;/*** 身份证号.*/private String cardNO;//.../*** 保存/更新前自动加密.*/@PrePersist@PreUpdatepublic void encrypt() {final String mobile = this.getMobile();final String cardNO = this.getCardNO();if (!SM4Util.startWithHeader(mobile)) {this.setMobile(SM4Util.encodeSM4Str(mobile));}if (!SM4Util.startWithHeader(cardNO)) {this.setCardNO(SM4Util.encodeSM4Str(cardNO));}}/*** 解密.*/@PostLoadpublic void decrypt() {// 解密.final String decodeMobile = SM4Util.decodeSM4Str(this.getMobile());final String decodeCardNO = SM4Util.decodeSM4Str(this.getCardNO());this.setMobile(decodeMobile);this.setCardNO(decodeCardNO);}
}
Spring Data JPA 从入门到精通~@PreUpdate异常场景分析相关推荐
- Spring Data JPA 从入门到精通~@Version处理乐观锁的问题
@Version 处理乐观锁的问题 @Version 乐观锁介绍 我们在研究 Auditing 的时候,发现了一个有趣的注解 @Version,源码如下: package org.springfram ...
- Spring Data JPA 从入门到精通~Auditing及其事件详解
Auditing 及其事件详解 Auditing 翻译过来是审计和审核,Spring 的优秀之处在于帮我们想到了很多繁琐事情的解决方案,我们在实际的业务系统中,针对一张表的操作大部分是需要记录谁什么时 ...
- spring data jpa从入门到精通_Spring Data JPA的简单入门
前言 spring data JPA是spring团队打造的sping生态全家桶的一部分,本身内核使用的是hibernate核心源码,用来作为了解java持久层框架基本构成的样本是再好不过的选择.最近 ...
- Spring Data JPA 从入门到精通~Naming命名策略详解及其实践
Naming 命名策略详解及其实践 用 JPA 离不开 @Entity 实体,我都知道实体里面有字段映射,而字段映射的方法有两种: 显式命名:在映射配置时,设置的数据库表名.列名等,就是进行显式命名, ...
- Spring Data JPA 从入门到精通~默认数据源的讲解
默认数据源 spring.datasource.driver-class-name=com.mysql.jdbc.Driver spring.datasource.url=jdbc:mysql://1 ...
- Spring Data JPA 从入门到精通~实际工作的应用场景
在实际工作中,有哪些场景会用到自定义 Repository 呢,这里列出几种实际在工作中的应用案例. 1. 逻辑删除场景 可以用到上面说的两种实现方式,如果有框架级别的全局自定义 Respositor ...
- Spring Data JPA 从入门到精通~自定义实现Repository
EntityManager 的获取方式 我们既然要自定义,首先讲一下 EntityManager 的两种获取方式. 1. 通过 @PersistenceContext 注解. 通过将 @Persist ...
- Spring Data JPA 从入门到精通~EntityManager介绍
EntityManager 介绍 我们前面已经无数次提到了,JPA 的默认 Repository 的实现类是 SimpleJpaRepository,而里面的具体实现就是调用的 EntityManag ...
- Spring Data JPA 从入门到精通~JpaSpecificationExecutor示例
新建两个实体 @Entity(name = "UserInfoEntity") @Table(name = "user_info", schema = &quo ...
最新文章
- 自动编码器的评级预测
- 项目工作展望(风来)
- Boost:点质心的测试程序
- Android 中英文语言切换
- GetType和typeof的区别
- Mysql索引类型分析
- 魔鬼作坊第一部实践----第九课
- 从小小后视镜看物联网的生态(下)
- android程序的建立,创建第一个Android程序 HelloWorld
- [转] 测试员,敢问路在何方(来自微软工程师)
- 无连续重复的随机算法
- 多位数据库专拣点评这本书
- 利用遗传算法求解TSP问题
- RINEX广播星历文件读取(N文件)
- Printf 输出格式总结
- 我在华为度过的 “两辈子”(学习那些在大厂表现优秀的人)
- POJ1260 Pearls(多重捆绑成0-1背包)
- 脉冲星 5 月脉动 | Pulsar 2.3.2 即将发布、2.4.0 预览、Pulsar 与 Camel 集成
- Type-C潮流下 如何衡量一款数据线好坏?
- iOS面试:简历模版(A4纸正反两面)