And*_*ite 47 java spring jpa spring-data spring-data-jpa
我有一个表Stuff定义为......
id, <fields>..., active
Run Code Online (Sandbox Code Playgroud)
Active是软删除标志,总是1或0.从长远来看,这可能会有利于历史表.
public interface StuffRepository extends JpaRepository<StuffEntity, Long> {}
Run Code Online (Sandbox Code Playgroud)
在代码中,我们总是 使用活动记录.有没有办法让Spring始终active=1为为此存储库生成的查询附加条件?或者更理想的是允许我扩展用于生成查询的语法?
我知道我可以@queues在任何地方创建命名,但后来我失去了生成的查询的便利性.我还想避免使用"主动"方法污染接口.
我正在使用Hibernate 4.2作为我的JPA实现,如果这很重要的话.
易天明*_*易天明 77
@Where(clause="is_active=1") 不是使用spring数据jpa处理软删除的最佳方法.
首先,它只适用于hibernate工具.
其次,您永远无法使用spring数据获取软删除的实体.
我的解决方案由弹簧数据提供.#{#entityName}表达式可用于通用存储库表示具体实体类型名称.
代码将是这样的:
//Override CrudRepository or PagingAndSortingRepository's query method:
@Override
@Query("select e from #{#entityName} e where e.deleteFlag=false")
public List<T> findAll();
//Look up deleted entities
@Query("select e from #{#entityName} e where e.deleteFlag=true")
public List<T> recycleBin();
//Soft delete.
@Query("update #{#entityName} e set e.deleteFlag=true where e.id=?1")
@Modifying
public void softDelete(String id);
Run Code Online (Sandbox Code Playgroud)
Sha*_*yam 75
这是一个老问题,你可能已经找到了答案.但是,对于那些寻求答案的所有Spring/JPA/Hibernate程序员来说 -
假设你有一个实体狗:
@Entity
public class Dog{
......(fields)....
@Column(name="is_active")
private Boolean active;
}
Run Code Online (Sandbox Code Playgroud)
和一个存储库:
public interface DogRepository extends JpaRepository<Dog, Integer> {
}
Run Code Online (Sandbox Code Playgroud)
您需要做的就是在实体级别添加@Where注释,从而产生:
@Entity
@Where(clause="is_active=1")
public class Dog{
......(fields)....
@Column(name="is_active")
private Boolean active;
}
Run Code Online (Sandbox Code Playgroud)
存储库执行的所有查询都将自动过滤掉"非活动"行.
vad*_*shb 27
基于易天明的回答,我用软件删除的覆盖方法创建了CrudRepository实现:
@NoRepositoryBean
public interface SoftDeleteCrudRepository<T extends BasicEntity, ID extends Long> extends CrudRepository<T, ID> {
@Override
@Transactional(readOnly = true)
@Query("select e from #{#entityName} e where e.isActive = true")
List<T> findAll();
@Override
@Transactional(readOnly = true)
@Query("select e from #{#entityName} e where e.id in ?1 and e.isActive = true")
Iterable<T> findAll(Iterable<ID> ids);
@Override
@Transactional(readOnly = true)
@Query("select e from #{#entityName} e where e.id = ?1 and e.isActive = true")
T findOne(ID id);
//Look up deleted entities
@Query("select e from #{#entityName} e where e.isActive = false")
@Transactional(readOnly = true)
List<T> findInactive();
@Override
@Transactional(readOnly = true)
@Query("select count(e) from #{#entityName} e where e.isActive = true")
long count();
@Override
@Transactional(readOnly = true)
default boolean exists(ID id) {
return findOne(id) != null;
}
@Override
@Query("update #{#entityName} e set e.isActive=false where e.id = ?1")
@Transactional
@Modifying
void delete(Long id);
@Override
@Transactional
default void delete(T entity) {
delete(entity.getId());
}
@Override
@Transactional
default void delete(Iterable<? extends T> entities) {
entities.forEach(entitiy -> delete(entitiy.getId()));
}
@Override
@Query("update #{#entityName} e set e.isActive=false")
@Transactional
@Modifying
void deleteAll();
}
Run Code Online (Sandbox Code Playgroud)
它可以与BasicEntity一起使用:
@MappedSuperclass
public abstract class BasicEntity {
@Column(name = "is_active")
private boolean isActive = true;
public abstract Long getId();
// isActive getters and setters...
}
Run Code Online (Sandbox Code Playgroud)
最终实体:
@Entity
@Table(name = "town")
public class Town extends BasicEntity {
@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "town_id_seq")
@SequenceGenerator(name = "town_id_seq", sequenceName = "town_id_seq", allocationSize = 1)
protected Long id;
private String name;
// getters and setters...
}
Run Code Online (Sandbox Code Playgroud)
Oli*_*ohm 10
在当前版本(最高1.4.1)中,Spring Data JPA中没有专门的软删除支持.但是,我强烈建议您使用DATAJPA-307的功能分支,因为这是即将发布的功能.
要使用当前状态更新您使用的版本1.5.0.DATAJPA-307-SNAPSHOT并确保让它引入它需要工作的特殊Spring Data Commons版本.您应该能够按照我们的示例测试用例来了解如何使这些工作正常工作.
PS:我们完成该功能后,我会更新问题.
| 归档时间: |
|
| 查看次数: |
30966 次 |
| 最近记录: |