我将vdshb提供的解决方案改编为 Spring JPA 存储库的较新版本。还添加了一些可能出现在您的企业应用程序中的常见字段。
基本实体:
@Data
@MappedSuperclass
public abstract class BasicEntity {
@Id
@GeneratedValue
protected Integer id;
protected boolean active = true;
@CreationTimestamp
@Column(updatable = false, nullable = false)
protected OffsetDateTime createdDate;
@UpdateTimestamp
@Column(nullable = false)
protected OffsetDateTime modifiedDate;
protected String createdBy = Constants.SYSTEM_USER;
protected String modifiedBy = Constants.SYSTEM_USER;
}
基本存储库:
@NoRepositoryBean
public interface BasicRepository<T extends BasicEntity, ID extends Integer> extends JpaRepository<T, ID> {
@Override
@Transactional(readOnly = true)
@Query("select e from #{#entityName} e where e.active = true")
List<T> findAll();
@Override
@Transactional(readOnly = true)
@Query("select e from #{#entityName} e where e.active = true and e.id = ?1")
Optional<T> findById(ID id);
@Override
@Transactional(readOnly = true)
@Query("select e from #{#entityName} e where e.id in ?1 and e.active = true")
List<T> findAllById(Iterable<ID> ids);
@Override
@Transactional(readOnly = true)
@Query("select e from #{#entityName} e where e.id = ?1 and e.active = true")
T getOne(ID id);
//Look up deleted entities
@Query("select e from #{#entityName} e where e.active = false")
@Transactional(readOnly = true)
List<T> findAllInactive();
@Override
@Transactional(readOnly = true)
@Query("select count(e) from #{#entityName} e where e.active = true")
long count();
@Override
@Transactional(readOnly = true)
default boolean existsById(ID id) {
return getOne(id) != null;
}
@Override
default void deleteById(ID id) {
throw new UnsupportedOperationException();
}
@Override
default void delete(T entity) {
throw new UnsupportedOperationException();
}
@Override
default void deleteAll(Iterable<? extends T> entities) {
throw new UnsupportedOperationException();
}
@Override
default void deleteAll() {
throw new UnsupportedOperationException();
}
/**
* Soft deletes entity in the database.
* It will not appear in the result set of default queries.
*
* @param id of the entity for deactivation
* @param modifiedBy who modified this entity
* @return deactivated entity with fetched fields
* @throws IncorrectConditionException when the entity is already deactivated.
* @throws NotFoundException when the entity is not found in the database.
*/
@Transactional
@Modifying
default T deactivate(ID id, String modifiedBy) throws IncorrectConditionException {
final T entity = findById(id)
.orElseThrow(() -> new NotFoundException(
String.format("Entity with ID [%s] wasn't found in the database. " +
"Nothing to deactivate.", id)));
if (!entity.isActive()) {
throw new IncorrectConditionException(String.format("Entity with ID [%s] is already deactivated.", id));
}
entity.setActive(false);
entity.setModifiedBy(modifiedBy);
return save(entity);
}
/**
* Activates soft deleted entity in the database.
*
* @param id of the entity for reactivation
* @param modifiedBy who modified this entity
* @return updated entity with fetched fields
* @throws IncorrectConditionException when the entity is already activated.
* @throws NotFoundException when the entity is not found in the database.
*/
@Transactional
@Modifying
default T reactivate(ID id, String modifiedBy) throws IncorrectConditionException {
final T entity = findById(id)
.orElseThrow(() -> new NotFoundException(
String.format("Entity with ID [%s] wasn't found in the database. " +
"Nothing to reactivate.", id)));
if (entity.isActive()) {
throw new IncorrectConditionException(String.format("Entity with ID [%s] is already active.", id));
}
entity.setActive(true);
entity.setModifiedBy(modifiedBy);
return save(entity);
}
}
如您所见,我UnsupportedOperationException
从删除方法中抛出。它是为了限制您的项目中没有经验的程序员调用这些方法。相反,您可以实现自己的删除方法。