2017-12-11 20 views
0

SpringデータJPA Repositoryを実装するインスタンスからエンティティタイプまたはクラス名を取得する方法を探しています。Spring Data - リポジトリからエンティティ名/タイプを取得

Repositoryインターフェイスを拡張し、いくつかの基本クエリを定義する基本インターフェイスを拡張した多数のインターフェイスがあります。

@NoRepositoryBean 
public interface EnumerationRepository<T extends IDatabaseEnumeration> extends Repository<T, String> { 
    // ... 
} 

public interface SampleEnumerationRepository extends EnumerationRepository<SampleEnumeration> { 

} 

春は私がジェネリックメソッドの内部簡単にアクセスMapにこれらの実装のすべてを置くことを望んでいた豆

@Autowired 
private Collection<EnumerationRepository<? extends IDatabaseEnumeration>> repositories; 

にコレクションとして、すべてのこれらのインタフェースの実装を注入することができます。エンティティのタイプや名前をキーとして使用したいと思っていましたが、どこから取得するかわかりません。これらの属性のいずれかを取得する方法はありますか?好ましくは、クラスタイプ。

このようなクエリを使用して、目的の動作を達成することができました。しかし、可能であれば、このソリューションを避けたいのですが、それは基盤となるDBに依存してしまうからです。彼らはこの答えを使用して、インタフェースからタイプにバインドされている場合は、型引数を取得することができます

@Query(value = "select '#{#entityName}' from dual", nativeQuery = true) 
public String getEntityName(); 
+0

「デュアルから」を削除し、nativeQueryの部分を削除してください。それは、バニラJPAクエリとして動作するはずです。 –

+0

それは不幸に働かなかった。今は、クエリが不完全なので、この例外が発生しています。 '原因:org.hibernate.hql.internal.ast.QuerySyntaxException:予期せぬサブツリーの終わり[select 'SampleEnumeration']' –

+0

私は個人的なプロジェクトでこれと同じことをしたことを100%誓いましたが、私は見つけることができませんそれは今です。私は今夜​​後でさらに検索します。その間、私は今のところ「デュアルから」ネイティブを残しておきます。 –

答えて

0

イェンス・schauderの答えは私の場合には動作しませんでした@が、それは私に正しい方向を示しました。

スプリングは私のインターフェイスのインプリメンテーションにバネRepositoryインターフェイスを追加しました。したがって、私はすべてのインターフェースを取得し、内部のものをフィルタリングしなければならなかったので、私が定義したもので終わった。これは一般的なものではありませんでしたので、私はスーパーインターフェースに汎用タイプを持っていなければなりませんでした。

このメソッドは、Springコンテナの初期化中にのみ呼び出されるため、パフォーマンスは実際には気にしません。

この場合、Fortunatelly多型は非常にうまく機能します。だから、私はスーパーインタフェースでデフォルトメソッドを実装するだけでした。このように

@NoRepositoryBean 
public interface EnumerationRepository<T extends IDatabaseEnumeration> extends Repository<T, String> { 

    // ... 

    default Class<T> getEntityClass() { 
     Type[] interfaces = getClass().getInterfaces(); 

     for (Type t : interfaces) { 
      if (t instanceof Class<?>) { 
       Class<?> clazz = (Class<?>) t; 

       if (clazz.getPackage().getName().startsWith(ApplicationConst.BASE_PACKAGE)) { 

        // Repositories should implement only ONE interface from application packages 

        Type genericInterface = clazz.getGenericInterfaces()[0]; 

        return (Class<T>) ((ParameterizedType) genericInterface).getActualTypeArguments()[0]; 
       } 
      } 
     } 

     return null; 
    } 

} 

これは、同様の問題に直面している他のユーザーにとって役に立ちます。

関連する問題