web-dev-qa-db-ja.com

JPAネイティブクエリ選択およびキャストオブジェクト

Adminを拡張するオブジェクトUserがあります。デフォルトでは、両方のオブジェクトがテーブルにありますUser_私のDerbyデータベース(Adminのフィールドを含む)。通常、次のようなUserを選択します。

CriteriaBuilder cb = em.getCriteriaBuilder();
CriteriaQuery<User> query = cb.createQuery(User.class);
Root user= query.from(User.class);
Predicate predicateId = cb.equal(category.get("id"), id);
query.select(user).where(predicateId);
return em.createQuery(query).getSingleResult();

ただし、クエリの複雑さのため、次のようなネイティブクエリを使用しています。

Query query = em.createNativeQuery("SELECT USER.* FROM USER_ AS USER WHERE ID = ?");
query.setParameter(1, id);
return (User) query.getSingleResult();

これはキャスト例外をスローしますが。これは、Adminのフィールドが原因であると考えられます。

私の質問は、最初の例と同じ結果のネイティブクエリを使用してUserを選択するにはどうすればよいですか(@LOBおよび@ManyToOne(et cetera)JPQLクエリが返すように)?

23
Menno

次のいずれかの方法を試してください。

  • を使用して メソッドcreateNativeQuery(sqlString, resultClass)

    ネイティブクエリは、EntityManager.createNativeQuery() APIを使用して動的に定義することもできます。

    String sql = "SELECT USER.* FROM USER_ AS USER WHERE ID = ?";
    
    Query query = em.createNativeQuery(sql, User.class);
    query.setParameter(1, id);
    User user = (User) query.getSingleResult();
    
  • を使用して 注釈@NamedNativeQuery

    ネイティブクエリは、@NamedNativeQueryおよび@NamedNativeQueriesアノテーション、または<named-native-query> XML要素によって定義されます。

    @NamedNativeQuery(
        name="complexQuery",
        query="SELECT USER.* FROM USER_ AS USER WHERE ID = ?",
        resultClass=User.class
    )
    public class User { ... }
    
    Query query = em.createNamedQuery("complexQuery", User.class);
    query.setParameter(1, id);
    User user = (User) query.getSingleResult();
    

優れたオープンブックで詳細を読むことができます Java Persistence (利用可能in [〜#〜] pdf [〜#〜] )。

────────
[〜#〜] note [〜#〜]getSingleResult()の使用に関してJPAでgetSingleResult()を使用しない理由 を参照してください。

49
Paul Vargas

受け入れられた答えは間違っています。

createNativeQueryは常にQueryを返します:

public Query createNativeQuery(String sqlString, Class resultClass);

getResultListQueryを呼び出すと、Listが返されます。

List getResultList()

List<MyEntity>に割り当てる(またはキャストする)と、未チェックの割り当て警告が生成されます。

一方、createQueryTypedQueryを返します。

public <T> TypedQuery<T> createQuery(String qlString, Class<T> resultClass);

getResultListTypedQueryを呼び出すと、List<X>が返されます。

List<X> getResultList();

これは適切に入力され、警告は表示されません。

createNativeQueryでは、ObjectMapperを使用することが警告を取り除く唯一の方法のようです。個人的には、これはライブラリーの欠陥であり、心配する必要のあるものではないと考えているため、警告を抑制することを選択します。

2
Derek White

JPA:ネイティブクエリの結果セットをPOJOクラスコレクションに変換する方法 を参照してください

ために Postgres 9.4

List<String> list = em.createNativeQuery("select cast(row_to_json(u) as text) from myschema.USER_ u WHERE ID = ?")
                   .setParameter(1, id).getResultList();

User map = new ObjectMapper().readValue(list.get(0), User.class);
2
Darshan Patel

ネイティブクエリが結合に基づいている場合、その場合、結果をオブジェクトのリストとして取得して処理できます。

一つの簡単な例。

@Autowired
EntityManager em;

    String nativeQuery = "select name,age from users where id=?";   
    Query query = em.createNativeQuery(nativeQuery);
    query.setParameter(1,id);

    List<Object[]> list = query.getResultList();

    for(Object[] q1 : list){

        String name = q1[0].toString();
        //..
        //do something more on 
     }
0
shankar