{"id":947,"date":"2012-10-17T13:26:39","date_gmt":"2012-10-17T18:26:39","guid":{"rendered":"http:\/\/alejandroayala.solmedia.ec\/?p=947"},"modified":"2012-10-17T13:27:24","modified_gmt":"2012-10-17T18:27:24","slug":"por-que-no-deberiamos-utilizar-getsingleresult-en-jpa","status":"publish","type":"post","link":"https:\/\/alejandroayala.solmedia.ec\/?p=947","title":{"rendered":"Por que no deber\u00edamos utilizar getSingleResult() en JPA"},"content":{"rendered":"<p style=\"text-align: justify;\">Hace tiempo que vengo usando JPA y he notado que el uso de <em><strong>getSingleResult<\/strong><\/em> y <em><strong>getResultList<\/strong><\/em> a menudo se confunde. En el <em>javadoc<\/em> no hay una explicaci\u00f3n clara de que usar:<\/p>\n<ul>\n<li><strong>getResultList()<br \/>\n<\/strong><span style=\"text-align: justify;\">Execute a SELECT query and return the query results as an untyped List.<br \/>\n<\/span><\/li>\n<li><strong style=\"text-align: justify;\">getSingleResult()<br \/>\n<\/strong><span style=\"text-align: justify;\">Execute a SELECT query that returns a single untyped result.<\/span><\/li>\n<\/ul>\n<p style=\"text-align: justify;\">As\u00ed que esto no es de mucha ayuda. Veamos que podemos hacer.<\/p>\n<p style=\"text-align: justify;\"><!--more--><\/p>\n<p style=\"text-align: justify;\">Ambos m\u00e9todos son usados para recibir <em>Entities<\/em> de la base de datos. Cuando usamos <em><strong>getResultList<\/strong>\u00a0<\/em>no sabemos la cantidad de resultados que vamos a recuperar, en cambio <em><strong>getSingleResult<\/strong><\/em>\u00a0se utiliza para recuperar exactamente un resultado(fila).<\/p>\n<p style=\"text-align: justify;\">La duda que surge es \u00bfen que casos nosotros queremos recuperar solo una fila? Un\u00a0ejemplo\u00a0perfecto\u00a0para este caso es cuando usamos consultas con el ID \u00fanico(<em><strong>findById<\/strong><\/em>), donde recuperamos un registro basados en su <strong>identificador \u00fanico<\/strong>.<br \/>\nHay tres maneras de hacer esto, la mas adecuada ser\u00eda usar el m\u00e9todo <em><strong>EntityManger.find()<\/strong><\/em>. Este m\u00e9todo retorna una instancia del tipo de la entidad cuando esta es encontrada. Las otras dos maneras es mediante un <em><strong>NamedQuery<\/strong><\/em>. Por que usar\u00edamos un <em><strong>NamedQuery<\/strong> <\/em>cuando tenemos el m\u00e9todo <em><strong>EntityManger.find()<\/strong><\/em>?. A veces tenemos que recuperar una colecci\u00f3n \u00ab<em>perezosa\u00bb<\/em>(<em><strong>lazzy<\/strong><\/em>) agregando a la consulta un<em> \u00abjoin\u00bb<\/em>. Otro ejemplo ser\u00eda cuando\u00a0nosotros\u00a0tenemos una <strong>clave compuesta<\/strong>, podr\u00edamos utilizar el m\u00e9todo <em><strong>EntityManger.find()<\/strong><\/em>, pero a menudo veo el uso de <em><strong>NamedQuery<\/strong> <\/em>en estos casos.(<strong>Mala pr\u00e1ctica de programaci\u00f3n, no lo hagas<\/strong>). Creamos nuestro NamedQuery.<\/p>\n<p>[java]<br \/>\nfinal Query query = getEntityManager().createNamedQuery(&quot;Entity.findById&quot;);<br \/>\nquery.setParameter(&quot;id&quot;, id);<br \/>\n[\/java]<\/p>\n<p style=\"text-align: justify;\">La reacci\u00f3n m\u00e1s natural es la de llamar a la <em><strong>getSingleResult<\/strong><\/em>. Esto devuelve una sola fila y el resultado de una consulta <em><strong>\u00abfindById\u00bb<\/strong><\/em> debe ser <strong>s\u00f3lo una fila<\/strong>. Pero <strong>\u00bfy si la fila no est\u00e1 en la base de datos?<\/strong> Recibimos una excepci\u00f3n sin control: <em><strong>NoResultException<\/strong><\/em>. Es esto lo que esperabas?<\/p>\n<p style=\"text-align: justify;\">Si nos fijamos en el libro <em>\u00ab<a href=\"http:\/\/www.amazon.com\/Effective-Java-2nd-Joshua-Bloch\/dp\/0321356683\">Effective Java<\/a>\u00ab<\/em> de<em> Joshua Bloch<\/em>: <em>\u00abUse checked exceptions for conditions from wich the caller can reasonably be expected to recover. Use runtime exceptions to indicate programming errors\u00bb<\/em>(Use excepciones comprobadas para condiciones de las cuales el usuario razonablemete espera recuperarse. Use excepciones de tiempo de ejecuci\u00f3n para indicar errores de programaci\u00f3n).<\/p>\n<p style=\"text-align: justify;\">Que nos quiere decir?. Cuando una consulta <em><strong>getSingleResult<\/strong><\/em> no devuelve nada, <strong>obtenemos una excepci\u00f3n no controlada<\/strong>, pues de un <strong>error del programador no hay forma de recuperarse<\/strong>. Esto no es correcto. Nunca sabemos a ciencia cierta que nos devolver\u00e1 la base de datos por lo que para este caso una excepci\u00f3n no controlada parece una mala elecci\u00f3n.<\/p>\n<p style=\"text-align: justify;\">El \u00fanico uso para <em><strong>getSingleResult<\/strong><\/em> es cuando ejecutamos una <strong>consulta escalar<\/strong>, por ejemplo: <strong>count, sum, avg<\/strong>. Esta consulta siempre devolver\u00e1 una fila, caso contrario estamos ante un caso excepcional, por lo que la excepci\u00f3n est\u00e1 permitida.<\/p>\n<p style=\"text-align: justify;\">Asi que \u00bfC\u00f3mo resolver nuestra consulta con NamedQuery?, f\u00e1cil:<\/p>\n<p>[java]<br \/>\nList results = query.getResultList();<br \/>\nEntity foundEntity = null;<br \/>\nif(!results.isEmpty()){<br \/>\n\/\/ ignores multiple results<br \/>\nfoundEntity = results.get(0);<br \/>\n}<br \/>\n[\/java]<\/p>\n<p style=\"text-align: justify;\">En este caso la lista <strong>contiene datos o esta vac\u00eda<\/strong>(<em>isEmpty<\/em>), no hay mas vuelta que dar. Luego si la lista no est\u00e1 vac\u00eda simplemente con un <em><strong>get(0)<\/strong><\/em> obtenemos nuestro valor, no hay \u00ab<em>sorpresas<\/em>\u00ab, si la base de datos no devuelve ninguna fila es <strong>f\u00e1cilmente controlable por el programador<\/strong>.<\/p>\n<p style=\"text-align: justify;\">Espero les sirva, cualquier cosa nos vemos en los comentarios.<\/p>\n<p style=\"text-align: justify;\">Fuente :\u00a0<a href=\"http:\/\/sysout.be\/2011\/03\/09\/why-you-should-never-use-getsingleresult-in-jpa\/\">http:\/\/sysout.be\/2011\/03\/09\/why-you-should-never-use-getsingleresult-in-jpa\/<\/a><\/p>\n\n<div class=\"twitter-share\"><a href=\"https:\/\/twitter.com\/intent\/tweet?via=a1ejo_ayala\" class=\"twitter-share-button\" data-size=\"large\">Twittear<\/a><\/div>\n","protected":false},"excerpt":{"rendered":"<p>Hace tiempo que vengo usando JPA y he notado que el uso de getSingleResult y getResultList a menudo se confunde. En el javadoc no hay una explicaci\u00f3n clara de que usar: getResultList() Execute a SELECT query and return the query results as an untyped List. getSingleResult() Execute a SELECT query that returns a single untyped\u2026 <span class=\"read-more\"><a href=\"https:\/\/alejandroayala.solmedia.ec\/?p=947\">Leer m\u00e1s &raquo;<\/a><\/span><\/p>\n","protected":false},"author":1,"featured_media":690,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_monsterinsights_skip_tracking":false,"_monsterinsights_sitenote_active":false,"_monsterinsights_sitenote_note":"","_monsterinsights_sitenote_category":0},"categories":[4],"tags":[140,206,207,209,205,204,29,506,203,208,210,507],"_links":{"self":[{"href":"https:\/\/alejandroayala.solmedia.ec\/index.php?rest_route=\/wp\/v2\/posts\/947"}],"collection":[{"href":"https:\/\/alejandroayala.solmedia.ec\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/alejandroayala.solmedia.ec\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/alejandroayala.solmedia.ec\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/alejandroayala.solmedia.ec\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=947"}],"version-history":[{"count":3,"href":"https:\/\/alejandroayala.solmedia.ec\/index.php?rest_route=\/wp\/v2\/posts\/947\/revisions"}],"predecessor-version":[{"id":950,"href":"https:\/\/alejandroayala.solmedia.ec\/index.php?rest_route=\/wp\/v2\/posts\/947\/revisions\/950"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/alejandroayala.solmedia.ec\/index.php?rest_route=\/wp\/v2\/media\/690"}],"wp:attachment":[{"href":"https:\/\/alejandroayala.solmedia.ec\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=947"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/alejandroayala.solmedia.ec\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=947"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/alejandroayala.solmedia.ec\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=947"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}