2

単一のスーパークラスから継承するクラスのセットがあります。

   Super
     |
     +------+-------+
     Aaaa   Bbbb    Cccc

次に、各Aaaa、Bbbb、CcccにメソッドfindByTagが含まれている必要があります。問題は、私がそれを一般的に定義することができないということです。次の例では、Aaaaの特定のfindByTagを定義しています。

public interface AaaaRepository extends SuperRepository<Aaaa> {
    @Query("select distinct a from Aaaa a " +
            "join a.tags t " +
            "join fetch a.locale where t = ?1")
    public List<Event> findByTag(Tag t);
}

スーパークラスは@MappedSuperclassであり、データベースに独自のテーブルがないことに注意してください。

各クラスでその名前に置き換えられるクエリで、ある種の「スーパー」を使用したいと思います。

2番目の問題は、@ElementCollectionを強制的にフェッチする方法がわからないことです。クエリでは常に「フェッチに参加」と明示的に言う必要があります。フェッチされていない場合、トランザクションが終了すると、明示的にフェッチしなかったオブジェクトにアクセスできなくなります。(LazyFetchの例外...)

ありがとう

4

3 に答える 3

2

このように書く代わりに、以下の疑似Javaコードに似たデータアクセスオブジェクトを作成します。

class DAO<T> {
     private Class<T> clazz;
     DAO( Class<T> class) { this.clazz = t; }
     @PersistenceContext
     private EntityManager em;

     public List<T> findByTag(Tag t ) {
        Query q = em.createQuery( "select from " + clazz.getSimpleName + "....";
        ...
        return q.getResultList();
     }
}

それが役に立てば幸い!

于 2012-02-04T16:11:28.810 に答える
2

ドキュメント、カスタム実装のセクションを見ると、このアプローチについてはどうでしょうか。

  1. リポジトリを拡張し、アノテーションなしでfindByTagメソッドを持つインターフェースを作成します。
  2. そのクラスの実装を作成し、メソッドの実装でJPA基準を使用します。ジェネリックはコンパイル時に消去されるため、ドメインオブジェクトの実際のクラスを保持するためのクラスフィールドも必要です。次に、そのフィールドを使用して基準を作成します。
  3. ドキュメントを読んで、この実装をリポジトリファクトリの基本クラスとして使用すると、SpringDataはこのカスタムリポジトリに基づいて他のリポジトリの実装を構築します。

    public interface MyRepository<T, ID> extends JpaRepository<T, ID> {        
        public List<Event> findByTag(Tag t);
    }
    
    public class MyRepositoryImpl<T, ID> implements MyRepository<T, ID> {
    
        private Class<T> actualClass; // initialized in the constructor
    
        public List<Event> findByTag(Tag t) {
             // here you build the criteria using actualClass field, and execute it.
        }
    }
    
    public interface AaaaRepository extends MyRepository <Aaaa, Integer> {
        // other methods...
    }
    

ファクトリBeanを作成するには、ドキュメントの「例1.16。カスタムリポジトリファクトリBean」を参照してください。

SpringがAaaaRepositoryの実装をインスタンス化するとき、基本クラスとしてMyRepositoryImplを使用します。

これはあなたのために働きますか?

于 2012-02-09T19:39:44.653 に答える
0

結局、Spring Data JPAの動作と柔軟性に不満があったので、簡単な方法でクエリを作成するための小さなツールを自分で作成しました。使用例は次のとおりです。

https://github.com/knyttl/Maite/wiki/Maite-Persistence

機能を定義する2つの子クラスと親クラスがあります。しかし、秘訣はクエリを構築するための流暢なインターフェースにあります。

まだ始まったばかりですが、すでに機能しているので、重複や正しい継承はありません。

親クラスの小さな例-詳細については、上記のリンクを確認してください。

@Autowired
EntityManager em;

protected abstract String getName();

protected Clause select() {
    return em
            .select("DISTINCT i")
            .from(this.getName(), "i")
            .joinFetch("i.locale lf")
}

public List<T> findByTag(Tag tag) {
    return (T) this.select()
            .join("i.tags t")
            .where("t = ?", tag)
            .fetchAll();
}
于 2012-02-15T22:56:33.350 に答える