1
0

feat(web): 实体软删除实现

This commit is contained in:
2024-12-01 15:20:39 +08:00
parent e134006794
commit 37267b4c7c
8 changed files with 141 additions and 8 deletions

View File

@@ -1,6 +1,11 @@
<component name="InspectionProjectProfileManager">
<profile version="1.0">
<option name="myName" value="Project Default" />
<inspection_tool class="DuplicatedCode" enabled="true" level="WEAK WARNING" enabled_by_default="true">
<Languages>
<language minSize="47" name="Java" />
</Languages>
</inspection_tool>
<inspection_tool class="HttpUrlsUsage" enabled="false" level="WEAK WARNING" enabled_by_default="false" />
</profile>
</component>

View File

@@ -0,0 +1,27 @@
package com.eshore.gringotts.web.domain.base.entity;
import javax.persistence.Column;
import javax.persistence.EntityListeners;
import javax.persistence.MappedSuperclass;
import lombok.Getter;
import lombok.Setter;
import lombok.ToString;
import org.springframework.data.jpa.domain.support.AuditingEntityListener;
/**
* 实体类公共字段
*
* @author lanyuanxiaoyao
* @date 2024-11-20
*/
@Getter
@Setter
@ToString(callSuper = true)
@MappedSuperclass
@EntityListeners(AuditingEntityListener.class)
public class LogicDeleteEntity extends SimpleEntity {
public static final String LOGIC_DELETE_CLAUSE = "deleted = false";
@Column(nullable = false)
private Boolean deleted = false;
}

View File

@@ -0,0 +1,27 @@
package com.eshore.gringotts.web.domain.base.entity;
import javax.persistence.Column;
import javax.persistence.EntityListeners;
import javax.persistence.MappedSuperclass;
import lombok.Getter;
import lombok.Setter;
import lombok.ToString;
import org.springframework.data.jpa.domain.support.AuditingEntityListener;
/**
* 实体类公共字段
*
* @author lanyuanxiaoyao
* @date 2024-11-20
*/
@Getter
@Setter
@ToString(callSuper = true)
@MappedSuperclass
@EntityListeners(AuditingEntityListener.class)
public class LogicDeleteIdOnlyEntity extends IdOnlyEntity {
public static final String LOGIC_DELETE_CLAUSE = "deleted = false";
@Column(nullable = false)
private Boolean deleted = false;
}

View File

@@ -0,0 +1,50 @@
package com.eshore.gringotts.web.domain.base.service;
import cn.hutool.core.util.ClassUtil;
import cn.hutool.core.util.StrUtil;
import com.eshore.gringotts.web.domain.base.entity.LogicDeleteEntity;
import com.eshore.gringotts.web.domain.base.repository.SimpleRepository;
import com.eshore.gringotts.web.domain.user.service.UserService;
import javax.persistence.EntityManager;
import javax.persistence.Query;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;
import javax.transaction.Transactional;
import lombok.extern.slf4j.Slf4j;
import org.eclipse.collections.api.factory.Lists;
import org.eclipse.collections.api.list.ImmutableList;
/**
* @author lanyuanxiaoyao
* @date 2024-11-21
*/
@Slf4j
public abstract class LogicDeleteService<ENTITY extends LogicDeleteEntity> extends SimpleServiceSupport<ENTITY> {
private final EntityManager manager;
public LogicDeleteService(SimpleRepository<ENTITY, Long> repository, UserService userService, EntityManager manager) {
super(repository, userService);
this.manager = manager;
}
@Override
protected ImmutableList<Predicate> extraListPredicates(Root<ENTITY> root, CriteriaQuery<?> query, CriteriaBuilder builder) {
return Lists.immutable.of(builder.equal(root.get("deleted"), false));
}
@Override
protected ImmutableList<Predicate> extraDetailPredicates(Root<ENTITY> root, CriteriaQuery<?> query, CriteriaBuilder builder) {
return Lists.immutable.of(builder.equal(root.get("deleted"), false));
}
@Transactional(rollbackOn = Throwable.class)
@Override
public void remove(Long id) {
String entityName = ClassUtil.getTypeArgument(this.getClass()).getSimpleName();
Query query = manager.createQuery(StrUtil.format("update {} entity set deleted=true where id=?1", entityName));
query.setParameter(1, id);
query.executeUpdate();
}
}

View File

@@ -9,7 +9,10 @@ import com.eshore.gringotts.web.domain.base.repository.SimpleRepository;
import com.eshore.gringotts.web.domain.user.entity.User;
import com.eshore.gringotts.web.domain.user.service.UserService;
import java.util.Optional;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;
import javax.transaction.Transactional;
import lombok.extern.slf4j.Slf4j;
import org.eclipse.collections.api.factory.Lists;
@@ -24,8 +27,8 @@ import org.springframework.data.domain.Sort;
*/
@Slf4j
public abstract class SimpleServiceSupport<ENTITY extends SimpleEntity> implements SimpleService<ENTITY> {
private final SimpleRepository<ENTITY, Long> repository;
private final UserService userService;
protected final SimpleRepository<ENTITY, Long> repository;
protected final UserService userService;
public SimpleServiceSupport(SimpleRepository<ENTITY, Long> repository, UserService userService) {
this.repository = repository;
@@ -64,6 +67,7 @@ public abstract class SimpleServiceSupport<ENTITY extends SimpleEntity> implemen
if (User.isNotAdministrator(user)) {
predicates.add(builder.equal(root.get("createdUser"), user));
}
predicates.addAllIterable(extraListPredicates(root, query, builder));
return builder.and(predicates.toArray(new Predicate[predicates.size()]));
},
Sort.by("createdTime").descending()
@@ -81,12 +85,17 @@ public abstract class SimpleServiceSupport<ENTITY extends SimpleEntity> implemen
if (User.isNotAdministrator(user)) {
predicates.add(builder.equal(root.get("createdUser"), user));
}
predicates.addAllIterable(extraListPredicates(root, query, builder));
return builder.and(predicates.toArray(new Predicate[predicates.size()]));
},
Sort.by("createdTime").descending()
));
}
protected ImmutableList<Predicate> extraListPredicates(Root<ENTITY> root, CriteriaQuery<?> query, CriteriaBuilder builder) {
return Lists.immutable.empty();
}
@Override
public Optional<ENTITY> detailOptional(Long id) {
if (ObjectUtil.isNull(id)) {
@@ -101,11 +110,16 @@ public abstract class SimpleServiceSupport<ENTITY extends SimpleEntity> implemen
if (User.isNotAdministrator(user)) {
predicates.add(builder.equal(root.get("createdUser"), user));
}
predicates.addAllIterable(extraDetailPredicates(root, query, builder));
return builder.and(predicates.toArray(new Predicate[predicates.size()]));
}
);
}
protected ImmutableList<Predicate> extraDetailPredicates(Root<ENTITY> root, CriteriaQuery<?> query, CriteriaBuilder builder) {
return Lists.immutable.empty();
}
@Override
public ENTITY detail(Long id) {
return detailOrNull(id);

View File

@@ -1,7 +1,7 @@
package com.eshore.gringotts.web.domain.confirmation.entity;
import com.eshore.gringotts.core.Constants;
import com.eshore.gringotts.web.domain.base.entity.SimpleEntity;
import com.eshore.gringotts.web.domain.base.entity.LogicDeleteEntity;
import com.eshore.gringotts.web.domain.resource.entity.DataResource;
import com.eshore.gringotts.web.domain.upload.entity.DataFile;
import java.util.Set;
@@ -25,6 +25,9 @@ import lombok.Getter;
import lombok.Setter;
import lombok.ToString;
import org.hibernate.annotations.DynamicUpdate;
import org.hibernate.annotations.SQLDelete;
import org.hibernate.annotations.Where;
import org.hibernate.annotations.WhereJoinTable;
import org.springframework.data.jpa.domain.support.AuditingEntityListener;
/**
@@ -50,9 +53,12 @@ import org.springframework.data.jpa.domain.support.AuditingEntityListener;
@NamedAttributeNode(value = "createdUser"),
@NamedAttributeNode(value = "modifiedUser"),
})
public class Confirmation extends SimpleEntity {
@SQLDelete(sql = "update " + Constants.TABLE_PREFIX + "confirmation" + " set deleted = true where id = ?")
@Where(clause = LogicDeleteEntity.LOGIC_DELETE_CLAUSE)
public class Confirmation extends LogicDeleteEntity {
@OneToOne(fetch = FetchType.EAGER)
@JoinColumn(nullable = false, foreignKey = @ForeignKey(ConstraintMode.NO_CONSTRAINT))
@WhereJoinTable(clause = LogicDeleteEntity.LOGIC_DELETE_CLAUSE)
private DataResource target;
private String description;
@OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY)

View File

@@ -2,7 +2,7 @@ package com.eshore.gringotts.web.domain.resource.entity;
import com.eshore.gringotts.core.Constants;
import com.eshore.gringotts.web.domain.authentication.entity.Authentication;
import com.eshore.gringotts.web.domain.base.entity.SimpleEntity;
import com.eshore.gringotts.web.domain.base.entity.LogicDeleteEntity;
import com.eshore.gringotts.web.domain.confirmation.entity.Confirmation;
import com.eshore.gringotts.web.domain.resource.entity.format.ResourceFormat;
import com.eshore.gringotts.web.domain.resource.entity.type.ResourceType;
@@ -25,6 +25,8 @@ import lombok.Getter;
import lombok.Setter;
import lombok.ToString;
import org.hibernate.annotations.DynamicUpdate;
import org.hibernate.annotations.SQLDelete;
import org.hibernate.annotations.Where;
import org.springframework.data.jpa.domain.support.AuditingEntityListener;
@Getter
@@ -48,7 +50,9 @@ import org.springframework.data.jpa.domain.support.AuditingEntityListener;
@NamedAttributeNode(value = "createdUser"),
@NamedAttributeNode(value = "modifiedUser"),
})
public class DataResource extends SimpleEntity {
@SQLDelete(sql = "update " + Constants.TABLE_PREFIX + "data_resource" + " set deleted = true where id = ?")
@Where(clause = LogicDeleteEntity.LOGIC_DELETE_CLAUSE)
public class DataResource extends LogicDeleteEntity {
@Column(nullable = false)
private String name;
private String description;

View File

@@ -1,7 +1,7 @@
package com.eshore.gringotts.web.domain.resource.entity.type;
import com.eshore.gringotts.core.Constants;
import com.eshore.gringotts.web.domain.base.entity.IdOnlyEntity;
import com.eshore.gringotts.web.domain.base.entity.LogicDeleteIdOnlyEntity;
import javax.persistence.Entity;
import javax.persistence.Inheritance;
import javax.persistence.InheritanceType;
@@ -22,7 +22,7 @@ import lombok.ToString;
@Entity
@Table(name = Constants.TABLE_PREFIX + "resource_type")
@Inheritance(strategy = InheritanceType.JOINED)
public abstract class ResourceType extends IdOnlyEntity {
public abstract class ResourceType extends LogicDeleteIdOnlyEntity {
public abstract Type getResourceType();
public enum Type {