JPA2.1 でアノテーション使わずに Named Query を登録するには

JPA 2.1 の javax.persistence.EntityManagerFactory#addNamedQuery() のはなし。

検索してもあまりヒットしないので。

普通の NamedQuery の使い方

JPA で NamedQuery 使う時は、Entity にアノテーション指定して以下のように定義する。

@Entity
@NamedQuery(name="Country.findAll", query="SELECT c FROM Country c") 
public class Country {
  ...
}

複数ある場合には、@NamedQueries で。

@Entity
@NamedQueries({
    @NamedQuery(name="Country.findAll",
                query="SELECT c FROM Country c"),
    @NamedQuery(name="Country.findByName",
                query="SELECT c FROM Country c WHERE c.name = :name"),
}) 
public class Country {
  ...
}

クエリは EntityManager の createNamedQuery で。

 TypedQuery<Country> query =
      em.createNamedQuery("Country.findAll", Country.class);
  List<Country> results = query.getResultList();

はい。普通です。

アノテーション使わない

JPA 2.1 で javax.persistence.EntityManagerFactoryaddNamedQuery(String name, Query query) が追加されました。

API はココ)

  em.getEntityManagerFactory().addNamedQuery(
      "Country.findAll", 
      em.createQuery("SELECT c FROM Country c"));

こんな感じでプログラマティックに Named Query を追加できます。

まぁ、使う機会ってそんなに無いかもしれませんが。

NamedQuery の名前は定数にしましょう

おまけ。 クエリ名は定数として定義しておくのが良いやりかたです。

先の例で言うと、以下のようになります。

@Entity
@NamedQuery(name=Country.FIND_ALL, query="SELECT c FROM Country c") 
public class Country {
  public static final String FIND_ALL = "Country.findAll";
  ...
}

クエリの実行も定数で。

 TypedQuery<Country> query =
      em.createNamedQuery(Country.FIND_ALL, Country.class);
  List<Country> results = query.getResultList();