JPAの名前付きクエリにリストを渡すことができますが、NamedNativeQueryはどうですか?私は多くの方法を試しましたが、それでもリストをNamedNativeQueryに渡すことはできません。 NamedNativeQueryのin句にリストを渡す方法を知っている人はいますか?どうもありがとうございました!
NamedNativeQueryは次のとおりです。
@NamedNativeQuery(
name="User.findByUserIdList",
query="select u.user_id, u.dob, u.name, u.sex, u.address from user u "+
"where u.user_id in (?userIdList)"
)
そして、それは次のように呼び出されます:
List<Object[]> userList = em.createNamedQuery("User.findByUserIdList").setParameter("userIdList", list).getResultList();
しかし、結果は思ったほどではありません。
System.out.println(userList.size()); //output 1
Object[] user = userList.get(0);
System.out.println(user.length); //expected 5 but result is 3
System.out.println(user[0]); //output MDAVERSION which is not a user_id
System.out.println(user[1]); //output 5
System.out.println(user[2]); //output 7
リストは、JDBCにバインドできないため、ネイティブSQLクエリの有効なパラメーターではありません。リスト内の各引数にパラメーターが必要です。
ここで、u.user_id in(?id1、?id2)
これはJPQLでサポートされますが、SQLではサポートされないため、ネイティブクエリの代わりにJPQLを使用できます。
一部のJPAプロバイダーはこれをサポートする場合があるため、プロバイダーにバグを記録することをお勧めします。
上記の受け入れられた答えは正しくなく、何日も私を軌道に乗せなかった!!
JPAとHibernateはどちらも、Queryを使用したネイティブクエリのコレクションを受け入れます。
あなたはただする必要があります
String nativeQuery = "Select * from A where name in :names"; //use (:names) for older versions of hibernate
Query q = em.createNativeQuery(nativeQuery);
q.setParameter("names", l);
また、同じことを示唆する回答を参照してください(上記の例をそのうちの1つから選択しました)
データベース/プロバイダー/ドライバーなどに応じて、実際には、JPAネイティブクエリにバインドされたパラメーターとしてリストを渡すことができます。
たとえば、PostgresとEclipseLinkを使用すると、次のように機能し(trueを返す)、多次元配列と倍精度の配列を取得する方法を示します。 (行う SELECT pg_type.* FROM pg_catalog.pg_type
他のタイプの場合;おそらく_
、しかしそれを使用する前に剥ぎ取ります。
Array test = entityManager.unwrap(Connection.class).createArrayOf("float8", new Double[][] { { 1.0, 2.5 }, { 4.1, 5.0 } });
Object result = entityManager.createNativeQuery("SELECT ARRAY[[CAST(1.0 as double precision), 2.5],[4.1, 5.0]] = ?").setParameter(1, test).getSingleResult();
キャストがあるため、リテラル配列は数値ではなく倍精度です。
質問のポイントまで-名前付きクエリをどのように、またはできるかはわかりません。多分それは依存すると思います。しかし、配列の場合は次のように動作すると思います。
Array list = entityManager.unwrap(Connection.class).createArrayOf("int8", arrayOfUserIds);
List<Object[]> userList = entityManager.createNativeQuery("select u.* from user u "+
"where u.user_id = ANY(?)")
.setParameter(1, list)
.getResultList();
私はOPと同じスキーマを持っていないので、これを正確に確認していませんが、少なくともPostgresとEclipseLinkでは動作するはずだと思います。
また、キーは次の場所にありました: http://tonaconsulting.com/postgres-and-multi-dimensions-arrays-in-jdbc/
Hibernate、JPA 2.1、およびdeltaspikeデータを使用して、IN句を含むクエリのパラメーターとしてリストを渡すことができます。私のクエリは以下です。
@Query(value = "SELECT DISTINCT r.* FROM EVENT AS r JOIN EVENT AS t on r.COR_UUID = t.COR_UUID where " +
"r.eventType='Creation' and t.eventType = 'Reception' and r.EVENT_UUID in ?1", isNative = true)
public List<EventT> findDeliveredCreatedEvents(List<String> eventIds);
HibernateをプロバイダーとしてJPA2で試してみたところ、hibernateは「IN」のリストの取得をサポートしており、動作するようです。 (少なくとも名前付きクエリでは、名前付きNATIVEクエリと似ていると思います)hibernateが内部的に行うのは、渡されたリストの要素数と同じIN内で動的パラメータを生成することです。
上記の例では
List<Object[]> userList = em.createNamedQuery("User.findByUserIdList").setParameter("userIdList", list).getResultList();
リストに2つの要素がある場合、クエリは次のようになります
select u.user_id, u.dob, u.name, u.sex, u.address from user u "+
"where u.user_id in (?, ?)
そして、それが3つの要素を持っている場合、それは次のようになります
select u.user_id, u.dob, u.name, u.sex, u.address from user u "+
"where u.user_id in (?, ?, ?)
現在、HibernateでJPA 2.1を使用しています
また、ネイティブクエリでIN条件を使用します。クエリの例
SELECT ... WHERE table_name.id IN (?1)
ただし、jpa 2.1 + hibernateを使用すると、文字列値のリストを渡すことができます。私の場合、次のコードは有効です:
List<String> idList = new ArrayList<>();
idList.add("344710");
idList.add("574477");
idList.add("508290");
query.setParameter(1, idList);
私の場合(EclipseLink、PostGreSQL)、これは動作します:
ServerSession serverSession = this.entityManager.unwrap(ServerSession.class);
Accessor accessor = serverSession.getAccessor();
accessor.reestablishConnection(serverSession);
BigDecimal result;
try {
Array jiraIssues = accessor.getConnection().createArrayOf("numeric", mandayWorkLogQueryModel.getJiraIssues().toArray());
Query nativeQuery = this.entityManager.createNativeQuery(projectMandayWorkLogQueryProvider.provide(mandayWorkLogQueryModel));
nativeQuery.setParameter(1,mandayWorkLogQueryModel.getPsymbol());
nativeQuery.setParameter(2,jiraIssues);
nativeQuery.setParameter(3,mandayWorkLogQueryModel.getFrom());
nativeQuery.setParameter(4,mandayWorkLogQueryModel.getTo());
result = (BigDecimal) nativeQuery.getSingleResult();
} catch (Exception e) {
throw new DataAccessException(e);
}
return result;
また、クエリでは次のようなエラーが発生するため、IN(?)を使用できません。
原因:org.postgresql.util.PSQLException:エラー:演算子が存在しません:数値=数値[]
「IN(?)」は「= ANY(?)」に交換する必要があります
私のソリューションは、エルハニスのコンセプトに基づいていました。