strategy query org name improvednamingstrategy example data column cfg java spring jpa spring-data spring-data-jpa

java - query - Manejo de borrado suave con Spring JPA



spring jpa hibernate naming strategy org hibernate cfg improvednamingstrategy (6)

Basado en la respuesta I, he creado la implementación CrudRepository con métodos modificados para la eliminación suave:

@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(); }

Se puede usar con BasicEntity:

@MappedSuperclass public abstract class BasicEntity { @Column(name = "is_active") private boolean isActive = true; public abstract Long getId(); // isActive getters and setters... }

Y entidad final:

@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... }

Tengo una tabla Stuff definidas como ...

id, <fields>..., active

Active es la bandera de borrado suave y siempre es 1 o 0 . A largo plazo esto puede desaparecer a favor de una tabla histórica.

public interface StuffRepository extends JpaRepository<StuffEntity, Long> {}

En el código, siempre usamos registros activos. ¿Hay alguna manera de hacer que Spring añada siempre una condición active=1 a las consultas generadas para este repositorio? ¿O más idealmente, permítame extender la gramática utilizada para generar las consultas?

Entiendo que puedo crear @queues nombre en todas partes, pero luego pierdo la comodidad de las consultas generadas. También quiero evitar contaminar la interfaz con métodos "activos".

Estoy utilizando Hibernate 4.2 como mi implementación de JPA si eso es importante.


En las versiones actuales (hasta 1.4.1) no hay soporte dedicado para eliminaciones suaves en Spring Data JPA. Sin embargo, le recomiendo encarecidamente que juegue con la rama de características para DATAJPA-307 ya que esta es una función actualmente trabajada para la próxima versión.

Para usar el estado actual, actualice la versión que usa a 1.5.0.DATAJPA-307-SNAPSHOT y asegúrese de dejar que se aplique la versión especial Spring Data Commons que necesita para funcionar. Debería poder seguir el caso de prueba de muestra que tenemos para ver cómo hacer que esas cosas funcionen.

PD: Actualizaré la pregunta una vez que hayamos terminado de trabajar en la función.


Esta es una vieja pregunta, y probablemente ya encontraste la respuesta. PERO, para todos los programadores de Spring / JPA / Hibernate que buscan respuesta -

Digamos que tienes una entidad Dog:

@Entity public class Dog{ ......(fields).... @Column(name="is_active") private Boolean active; }

y un repositorio

public interface DogRepository extends JpaRepository<Dog, Integer> { }

Todo lo que necesita hacer es agregar la anotación @Where en el nivel de la entidad, lo que da como resultado:

@Entity @Where(clause="is_active=1") public class Dog{ ......(fields).... @Column(name="is_active") private Boolean active; }

Todas las consultas realizadas por el repositorio filtrarán automáticamente las filas "no activas".


Puede extender desde SimpleJpaRepository y crear su propio repositorio personalizado donde puede definir la funcionalidad de borrado suave de una manera genérica.

También necesitarás crear un JpaRepositoryFactoryBean personalizado y habilitarlo en tu clase principal.

Puedes consultar mi código aquí https://github.com/dzinot/spring-boot-jpa-soft-delete


Sugiero que use una vista de base de datos (o equivalente en Oracle) si no desea importar anotaciones específicas de hibernación. En mySQL 5.5, estas vistas pueden ser actualizadas e insertables si el criterio de filtro es tan simple como activo = 1

crear o reemplazar ver active_stuff como select * from Stuff donde active = 1;

Si esta es una buena idea, probablemente dependa de su base de datos, pero funciona muy bien en mi implementación.

La desactivación requirió una entidad adicional que accedió a ''Cosas'' directamente, pero también lo haría @Where


@Where(clause="is_active=1") no es la mejor manera de manejar la eliminación suave con datos de primavera jpa.

En primer lugar, solo funciona con el instrumento de hibernación.

En segundo lugar, nunca puede buscar entidades eliminadas con datos de primavera.

Mi solución es el proporcionado por los datos de primavera. #{#entityName} expresión #{#entityName} se puede usar en un repositorio genérico para representar el nombre del tipo de entidad concreta.

Y el código será así:

//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);