with query example constructorresult jpa map resultset openjpa

jpa - query - resultset hibernate



¿Puede JPA devolver los resultados como un mapa? (6)

Con la class resultados personalizada y un poco de guayaba, este es mi enfoque que funciona bastante bien:

public static class SlugPair { String canonicalSlug; String slug; public SlugPair(String canonicalSlug, String slug) { super(); this.canonicalSlug = canonicalSlug; this.slug = slug; } }

...

final TypedQuery<SlugPair> query = em.createQuery( "SELECT NEW com.quikdo.core.impl.JpaPlaceRepository$SlugPair(e.canonicalSlug, e.slug) FROM " + entityClass.getName() + " e WHERE e.canonicalSlug IN :canonicalSlugs", SlugPair.class); query.setParameter("canonicalSlugs", canonicalSlugs); final Map<String, SlugPair> existingSlugs = FluentIterable.from(query.getResultList()).uniqueIndex( new Function<SlugPair, String>() { @Override @Nullable public String apply(@Nullable SlugPair input) { return input.canonicalSlug; } });

Actualmente estamos construyendo un mapa manualmente en función de los dos campos que devuelve una consulta con nombre, porque JPA solo proporciona un getResultList ()

@NamedQuery{name="myQuery",query="select c.name, c.number from Client c"} HashMap<Long,String> myMap = new HashMap<Long,String>(); for(Client c: em.createNamedQuery("myQuery").getResultList() ){ myMap.put(c.getNumber, c.getName); }

Pero creo que un mapeador personalizado o similar sería más eficaz ya que esta lista podría tener más de 30,000 resultados.

Cualquier idea para construir un mapa sin iterar manualmente.

(Estoy usando OpenJPA, no hibernando)


No hay una forma estándar de obtener JPA para devolver un mapa.

Consulte la pregunta relacionada: Resultados de consultas nativas JPA 2.0 como mapa

Iterar manualmente debería estar bien. El tiempo para iterar una lista / mapa en la memoria será pequeño en relación con el tiempo para ejecutar / devolver los resultados de la consulta. No trataría de utilizar las internas o la personalización de JPA a menos que hubiera pruebas concluyentes de que la iteración manual no era viable.

Además, si tiene otros lugares en los que convierta las Listas de resultados de la consulta en Mapas, probablemente desee refactorizar eso en un método de utilidad con un parámetro para indicar la propiedad clave del mapa.


Por favor refiérase, resultados de la consulta nativa JPA 2.0 como mapa

En tu caso en Postgres , sería algo así como,

List<String> list = em.createNativeQuery("select cast(json_object_agg(c.number, c.name) as text) from schema.client c") .getResultList(); //handle exception here, this is just sample Map map = new ObjectMapper().readValue(list.get(0), Map.class);

Por favor, estoy compartiendo mi solución con Postgres.


Puede recuperar una lista de java.util. Map.Entry en su lugar. Por lo tanto, la colección en su entidad debe modelarse como un Mapa:

@OneToMany @MapKeyEnumerated(EnumType.STRING) public Map<PhoneType, PhoneNumber> phones;

En el ejemplo, PhoneType es una enumeración simple, PhoneNumber es una entidad. En su consulta, use la palabra clave ENTRY que se introdujo en JPA 2.0 para las operaciones de mapas:

public List<Entry> getPersonPhones(){ return em.createQuery("SELECT ENTRY(pn) FROM Person p JOIN p.phones pn",java.util.Map.Entry.class).getResultList(); }

Ahora está listo para recuperar las entradas y comenzar a trabajar con ellas:

List<java.util.Map.Entry> phoneEntries = personDao.getPersonPhoneNumbers(); for (java.util.Map.Entry<PhoneType, PhoneNumber> entry: phoneEntries){ //entry.key(), entry.value() }

Si aún necesita las entradas en un mapa pero no quiere recorrer su lista de entradas manualmente, consulte esta publicación Convert Set <Map.Entry <K, V >> to HashMap <K, V> que funciona con Java 8.


Qué tal esto ?

@NamedNativeQueries({ @NamedNativeQuery( name="myQuery", query="select c.name, c.number from Client c", resultClass=RegularClient.class ) })

y

public static List<RegularClient> runMyQuery() { return entityManager().createNamedQuery("myQuery").getResultList(); }


Esto funciona bien.
Código del repositorio:

@Repository public interface BookRepository extends CrudRepository<Book,Id> { @Query("SELECT b.name, b.author from Book b") List<Object[]> findBooks(); }

service.java

List<Object[]> list = bookRepository.findBooks(); for (Object[] ob : list){ String key = (String)ob[0]; String value = (String)ob[1]; }

enlace https://codereview.stackexchange.com/questions/1409/jpa-query-to-return-a-map