Este problema me ha dado la lata un buen rato. Me animo con este post porque no he encontrado prácticamente ninguna información sobre cómo hacer esto. El problema que queremos solucionar es sencillo de explicar:
Tenemos una entidad llamada FooData. Queremos recuperar n objetos fooData aleatorios.
Suponiendo que la tabla correspondiente a FooData es foo, en mysql podemos resolver nuestro problema con una query tal que así:
1
|
|
En Oracle 9 la query es un poco más compleja, sobre todo por la parte de limitar el número de registros a devolver, que se resuelve con una subquery:
1 2 3 |
|
Una vez que sabemos resolver nuestro problema en SQL y que ya hemos visto que no hay una solución estándar, vamos a tratar de implementarlo mediante HQL.
La parte de obtener únicamente n resultados es trivial, ya que disponemos del método org.hibernate.Query.setMaxResults(int arg0). El esqueleto de nuestro código sería parecido a:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
|
Donde será necesario sustituir CUSTOM_QUERY_ORACLE y CUSTOM_QUERY_MYSQL por los valores adecuados en cada una de las ramas del if.
HQL para obtener n registros aleatorios con MySQL
Para hacer esta consulta con HQL “sobre” mysql, la traducción es casi directa. Eliminamos el limit, pues ya limitamos el número de resultados con setMaxResults() y cambiamos el nombre de la tabla por el nombre de la entidad, de modo que en el ejemplo anterior donde teníamos CUSTOM_QUERY_MYSQL, ahora tendremos:.
1
|
|
HQL para obtener n registros aleatorios con Oracle 9
Esta traducción es casi tan trivial como la anterior, pero con matices. Utilizando la misma lógica que en el apartado anterior llegamos a una query más o menos así:
1
|
|
Esta query no funciona, pues nuestro amigo Hibernate trata de buscar el atributo value de la entidad dbms_random. Y no encuentra el mapping, porque no lo hay. Solo tenemos que buscar la manera de que la BD reciba la query adecuada. Tras un buen rato de ensayo-error, llegamos a la siguiente solución:
1
|
|
Ahora nuestro driver si que es capaz de “saber” que dbms_random.random() no es cosa suya y que lo único que tiene que hacer es dejar pasar ese trocito de query para que Oracle juegue con el.
Sustituyendo CUSTOM_QUERY_ORACLE por esta última query, ya tendremos el puzzle completo.
Lo sentimos, pero los comentarios están cerrados
Gracias por la instrucción query.setMaxResults(amount); era justo lo que necesitaba.
Saludos
Muchísimas gracias por tu tiempo y por el dbms_random.random(). Nos ha servido de mucho.
Gracias, me sirvió de mucho
Excelente, me funciona a la perfección, saludos
Muchas gracias! dbms_random.random() era justo lo que buscaba :) ! saludos!