2010-12-06 26 views
20

Actualmente estamos compilando un mapa de forma manual en función de los dos campos que devuelve una consulta con nombre, porque JPA solo proporciona un getResultList().¿Puede JPA devolver los resultados como un mapa?

@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 me siento como un asignador de costumbre o similar sería con más prestaciones ya que esta lista podría ser fácilmente más de 30.000 resultados.

Todas las ideas para crear un mapa sin iterar manualmente.

(estoy usando OpenJPA, no hibernar)

+0

¿Qué se usaría como su clave de mapa? –

+0

Al igual que el código muestra, el campo de número (Largo), uno de los dos valores devueltos. PERO podría vivir con cualquier Tipo, siempre y cuando la clave sea el número y el valor sea el nombre. Agregué la declaración para más detalles. – Eddie

Respuesta

0

¿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(); 
} 
+0

@zawhut - gracias, pero esto todavía devuelve una lista ... El problema es que necesito usar los resultados dentro de otro método y necesito un método de búsqueda rápido ... Pensé que un mapa sería la mejor manera de hacerlo. – Eddie

14

No hay manera estándar para obtener la APP para regresar un mapa.

ver pregunta relacionada: JPA 2.0 native query results as map

iteración de forma manual debe estar bien. El tiempo para iterar una lista/mapa en memoria va a ser pequeño en relación con el tiempo para ejecutar/devolver los resultados de la consulta. No trataría de utilizar las funciones 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 donde puede convertir las listas de resultados de la consulta en Mapas, probablemente desee refaccionarlo en un método de utilidad con un parámetro para indicar la propiedad de la clave del mapa.

0

Con el resultado a medida class 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; 
    } 
}); 
4

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

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

En el ejemplo PhoneType es una enumeración simple, Fax es una entidad. En la consulta utilizar la palabra clave ENTRY que se introdujo en JPA 2.0 para operaciones de correlación:

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

que ahora está listo para recuperar las entradas y empezar a trabajar con él:

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 la entradas en un mapa, pero no desea iterar manualmente a través de su lista de entradas, eche un vistazo a esta publicación Convert Set<Map.Entry<K, V>> to HashMap<K, V> que funciona con Java 8.

0

Por favor remítase, JPA 2.0 native query results as map

En su 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); 

KindlyNote, sólo estoy compartiendo mi solución con Postgres.

Cuestiones relacionadas