71

Stuff次のように定義されたテーブルがあります...

id, <fields>..., active

Active はソフト削除フラグで、常に1または0です。長期的には、これは履歴テーブルを優先してなくなる可能性があります。

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

コードでは、常に アクティブ レコードを使用します。active=1このリポジトリ用に生成されたクエリに常に条件を追加するように Spring を取得する方法はありますか? または、より理想的には、クエリの生成に使用される文法を拡張できるようにしますか?

@queuesどこでも名前付きを作成できることは理解していますが、生成されたクエリの利便性が失われます。また、「アクティブな」メソッドでインターフェイスを汚染することも避けたいと考えています。

それが重要な場合、JPA実装としてHibernate 4.2を使用しています。

4

9 に答える 9

123

@Where(clause="is_active=1")spring data jpa でソフト削除を処理する最良の方法ではありません。

まず、休止状態の実装でのみ機能します。

次に、Spring データを使用して論理的に削除されたエンティティを取得することはできません。

私の解決策は、春のデータによって提供されるelです。#{#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); 
于 2015-10-16T10:48:58.807 に答える
108

これは古い質問であり、おそらくすでに答えを見つけているでしょう。しかし、答えを求めているすべてのSpring / JPA / Hibernateプログラマーにとって-

エンティティ Dog があるとします。

 @Entity
 public class Dog{

 ......(fields)....        

 @Column(name="is_active")
 private Boolean active;
 }

およびリポジトリ:

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

エンティティ レベルで @Where アノテーションを追加するだけで、次のようになります。

@Entity
@Where(clause="is_active=1")
public class Dog{

......(fields)....        

@Column(name="is_active")
private Boolean active;
}

リポジトリによって実行されるすべてのクエリは、「非アクティブ」行を自動的に除外します。

于 2014-03-05T15:48:10.463 に答える
12

現在のバージョン (1.4.1 まで) では、Spring Data JPA でのソフト削除の専用サポートはありません。ただし、DATAJPA-307の機能ブランチを試してみることを強くお勧めします。これは、今後のリリースに向けて現在取り組んでいる機能です。

現在の状態を使用するには、使用するバージョンを 1.5.0.DATAJPA-307-SNAPSHOT に更新し、動作に必要な特別な Spring Data Commons バージョンをプルできるようにしてください。サンプルのテスト ケースに従うことができるはずです。その方法を確認する必要があります。

PS: 機能の作業が完了したら、質問を更新します。

于 2013-10-13T11:47:33.153 に答える
0

このようなリポジトリを定義しました

@NoRepositoryBean
public interface SoftDeleteRepository<T, ID extends Serializable> extends JpaRepository<T, ID>,
    JpaSpecificationExecutor<T> {

    enum StateTag {
        ENABLED(0), DISABLED(1), DELETED(2);

        private final int tag;

        StateTag(int tag) {
            this.tag = tag;
        }

        public int getTag() {
            return tag;
        }
    }

    T changeState(ID id, StateTag state);

    List<T> changeState(Iterable<ID> ids, StateTag state);

    <S extends T> List<S> changeState(Example<S> example, StateTag state);

    List<T> findByState(@Nullable Iterable<StateTag> states);

    List<T> findByState(Sort sort, @Nullable Iterable<StateTag> states);

    Page<T> findByState(Pageable pageable, @Nullable Iterable<StateTag> states);

    <S extends T> List<S> findByState(Example<S> example, @Nullable Iterable<StateTag> states);

    <S extends T> List<S> findByState(Sort sort, Example<S> example, @Nullable Iterable<StateTag> states);

    <S extends T> Page<S> findByState(Pageable pageable, Example<S> example,
                                  @Nullable Iterable<StateTag> states);

    long countByState(@Nullable Iterable<StateTag> states);

    default String getSoftDeleteColumn() {
        return "disabled";
    }
}
于 2019-01-10T09:09:43.147 に答える