惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

T
Tenable Blog
月光博客
月光博客
雷峰网
雷峰网
WordPress大学
WordPress大学
博客园 - 司徒正美
Last Week in AI
Last Week in AI
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
V
Visual Studio Blog
H
Help Net Security
Engineering at Meta
Engineering at Meta
Google DeepMind News
Google DeepMind News
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
K
KPMG report finds enterprise disconnect between AI and its ROI | CIO
S
Security @ Cisco Blogs
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
爱范儿
爱范儿
W
WeLiveSecurity
J
Java Code Geeks
Forbes - Security
Forbes - Security
H
Hacker News: Front Page
T
Threatpost
The Cloudflare Blog
C
Cyber Attacks, Cyber Crime and Cyber Security
N
Netflix TechBlog - Medium
Latest news
Latest news
V2EX - 技术
V2EX - 技术
小众软件
小众软件
T
The Blog of Author Tim Ferriss
A
Arctic Wolf
B
Blog RSS Feed
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
I
InfoQ
C
Check Point Blog
N
News | PayPal Newsroom
Cyberwarzone
Cyberwarzone
V
V2EX
TaoSecurity Blog
TaoSecurity Blog
P
Privacy & Cybersecurity Law Blog
Microsoft Security Blog
Microsoft Security Blog
CTFtime.org: upcoming CTF events
CTFtime.org: upcoming CTF events
D
DataBreaches.Net
F
Fortinet All Blogs
阮一峰的网络日志
阮一峰的网络日志
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
IT之家
IT之家
K
Kaspersky official blog
cs.CV updates on arXiv.org
cs.CV updates on arXiv.org
Google DeepMind News
Google DeepMind News
C
CXSECURITY Database RSS Feed - CXSecurity.com
www.infosecurity-magazine.com
www.infosecurity-magazine.com

博客园 - 张占岭

springboot~关于构造方法注入和字段注入的选择 apisix~OpenResty各阶段的介绍 keycloak~aud受众字段的作用及如何生成 wso2~关于workbuddy中mcp在wso2中的授权端点 k8s~避免调度资源碎片化 WEB安全~csrf介绍 WEB安全~DPoP的介绍 WEB安全~csp的介绍 什么是中间人攻击 WEB安全~xss的介绍 k8s~pod资源限制和JVM的XMX配置 关于对wso2和keycloak的token交换的调研 keycloak~实现OAuth 2.0 Token Exchange backstage~实体的介绍及它们的关系 backstage~openapi的接入与protobuf的对比 backstage~将java服务添加到backstage backstage~对接github和gitlab backstage~开始一个backstage应用 apisix~graphQL的支持 wso2几个核心项目介绍 docker~BuildKit的介绍 k8s~secret资源的使用 算法~时间戳计算两个日期是否为同天同时同分 wso2~4.5升级到4.6需要更新的数据表 backstage~Backstage的概述 springboot~ImportBeanDefinitionRegistrar在自定义RPC框架中的使用 keycloak~深入了解DefaultSegmentedDataContainer对象解决内存泄漏 keycloak~分布式部署中会话过期清理机制 wso2~通过三方IDP的token置换wso2的token jmeter进行接口压测 Keycloak~infinispan中MergedUpdate中lifespanMs和maxIdleTimeMs wso2~添加mcp服务的注意点
springboot~jpa优雅的软删除能力
张占岭 · 2026-03-03 · via 博客园 - 张占岭

之前写过关于springboot~jpa优雅的处理isDelete的默认值的文章,今天说一下在jpa或者其它类型的Repository中实现软删除的方法,主要借助了自定义的仓储的能力。

优雅的引用方式

/**
 * 开启软删除的能力
 *
 * @author lind
 * @date 2025/9/8 11:24
 * @since 1.0.0
 */
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@EnableJpaRepositories(repositoryBaseClass = SoftDeleteRepositoryImpl.class)
public @interface EnableSoftDeleteRepository {

}

接口标准化

/**
 * 软删除能力,通过@EnableSoftDeleteRepository注解开启功能,通过接口继承的方式实现这个能力
 *
 * @param <T>
 * @param <ID>
 */
@NoRepositoryBean // 不让jpa使用代理建立实现类
public interface SoftDeleteRepository<T, ID> {

	T getEntityById(ID id);

	/**
	 * 希望重写findById方法
	 * @param id
	 * @return
	 */
	T getById(ID id);

}

覆盖默认的deleteById方法,实现软删除

/**
 * 自定义的公共仓储的实现
 *
 * @param <T>
 * @param <ID>
 */
public class SoftDeleteRepositoryImpl<T, ID> extends SimpleJpaRepository<T, ID> implements SoftDeleteRepository<T, ID> {

	private final EntityManager entityManager;

	private final JpaEntityInformation<T, ID> jpaEntityInformation;

	Class<T> domainType;

	Logger logger = LoggerFactory.getLogger(SoftDeleteRepositoryImpl.class);

	public SoftDeleteRepositoryImpl(JpaEntityInformation<T, ID> jpaEntityInformation, EntityManager entityManager) {
		super(jpaEntityInformation, entityManager); // 必须调用父类构造函数
		this.entityManager = entityManager;
		this.jpaEntityInformation = jpaEntityInformation;
		this.domainType = jpaEntityInformation.getJavaType();
	}

	@Override
	public T getEntityById(ID id) {
		return entityManager.find(this.domainType, id);
	}

	/**
	 * @param id
	 * @deprecated
	 */
	@Override
	public void deleteById(ID id) {
		logger.info("CustomRepositoryImpl.getById " + id);
		T entity = getEntityById(id);
		if (entity != null && entity instanceof DeletedFlagField) {
			((DeletedFlagField) entity).setDeletedFlag(1);
			entityManager.merge(entity);
		}
		else {
			super.deleteById(id);
		}
	}

}

需要实现软删除的仓库接口上,继承这个接口即有这个软删除的能力

/**
 * 用户仓储
 *
 * @author lind
 * @date 2025/7/15 15:56
 * @since 1.0.0
 */
public interface UserEntityRepository extends SoftDeleteRepository<UserEntity, String>,
		JpaRepository<UserEntity, String>, JpaSpecificationExecutor<UserEntity> {

}