El concepto de Java Optional Repository llega en Java 8 y hace referencia a cómo podemos usar los tipos Optional dentro de nuestras clases clásicas de repositorio. El ejemplo mas clásico es el método BuscarUno o findOne() a nivel de Java Persistence API . Este método nos permite buscar un elemento concreto por clave primaria utilizando el repositorio.
En muchas ocasiones el programa puede dar problemas en el caso de que no se encuentre ningún elemento ya que cuando intentamos acceder a sus campos saltará una excepción de tipo NullPointer.
&lt;br&gt;<br>
package repositorios.ejemplo1;&lt;/p&gt;<br>
&lt;p&gt;import javax.persistence.EntityManager;&lt;/p&gt;<br>
&lt;p&gt;import model.Cliente;&lt;/p&gt;<br>
&lt;p&gt;public class ClienteRepository {&lt;/p&gt;<br>
&lt;p&gt; private EntityManager entityManager;&lt;/p&gt;<br>
&lt;p&gt; public EntityManager getEntityManager() {&lt;br&gt;<br>
return entityManager;&lt;br&gt;<br>
}&lt;/p&gt;<br>
&lt;p&gt; public void setEntityManager(EntityManager entityManager) {&lt;br&gt;<br>
this.entityManager = entityManager;&lt;br&gt;<br>
}&lt;/p&gt;<br>
&lt;p&gt; public Cliente buscarUno(String dni) {&lt;/p&gt;<br>
&lt;p&gt; return entityManager.find(Cliente.class, "1");&lt;br&gt;<br>
}&lt;br&gt;<br>
}&lt;/p&gt;<br>
&lt;p&gt; &lt;br&gt;<br>
package repositorios;&lt;/p&gt;<br>
&lt;p&gt;import javax.persistence.EntityManager;&lt;br&gt;<br>
import javax.persistence.EntityManagerFactory;&lt;br&gt;<br>
import javax.persistence.Persistence;&lt;/p&gt;<br>
&lt;p&gt;import model.Cliente;&lt;br&gt;<br>
import repositorios.ejemplo1.ClienteRepository;&lt;/p&gt;<br>
&lt;p&gt;public class Principal {&lt;/p&gt;<br>
&lt;p&gt; public static void main(String[] args) {&lt;/p&gt;<br>
&lt;p&gt; EntityManagerFactory emf = Persistence.createEntityManagerFactory("jpa001");&lt;br&gt;<br>
EntityManager em = emf.createEntityManager();&lt;/p&gt;<br>
&lt;p&gt; ClienteRepository repositorio = new ClienteRepository();&lt;/p&gt;<br>
&lt;p&gt; Cliente cliente=repositorio.buscarUno("1");&lt;br&gt;<br>
System.out.println(cliente.getNombre());&lt;/p&gt;<br>
&lt;p&gt; }&lt;/p&gt;<br>
&lt;p&gt;}&lt;/p&gt;<br>
&lt;p&gt; Java Optional Repository
Para evitar estos problemas podemos apoyarnos en Java 8 y hacer uso de los tipos Optional que nos obligan a comprobar si un tipo esta a null antes de acceder a la información que almacena.
Veámoslos en código:
&lt;/p&gt;<br>
&lt;p&gt;package repositorios.ejemplo2;&lt;/p&gt;<br>
&lt;p&gt;import java.util.Optional;&lt;/p&gt;<br>
&lt;p&gt;import javax.persistence.EntityManager;&lt;br&gt;<br>
import javax.persistence.EntityManagerFactory;&lt;br&gt;<br>
import javax.persistence.Persistence;&lt;/p&gt;<br>
&lt;p&gt;import model.Cliente;&lt;/p&gt;<br>
&lt;p&gt;public class ClienteRepository {&lt;/p&gt;<br>
&lt;p&gt; private EntityManager entityManager;&lt;/p&gt;<br>
&lt;p&gt; public EntityManager getEntityManager() {&lt;br&gt;<br>
return entityManager;&lt;br&gt;<br>
}&lt;/p&gt;<br>
&lt;p&gt; public void setEntityManager(EntityManager entityManager) {&lt;br&gt;<br>
this.entityManager = entityManager;&lt;br&gt;<br>
}&lt;/p&gt;<br>
&lt;p&gt; public ClienteRepository(EntityManager entityManager) {&lt;br&gt;<br>
super();&lt;br&gt;<br>
this.entityManager = entityManager;&lt;br&gt;<br>
}&lt;/p&gt;<br>
&lt;p&gt; public Optional&amp;lt;Cliente&amp;gt; buscarUno(String dni) {&lt;/p&gt;<br>
&lt;p&gt; Cliente cliente = entityManager.find(Cliente.class, dni);&lt;/p&gt;<br>
&lt;p&gt; if (cliente == null) {&lt;/p&gt;<br>
&lt;p&gt; return Optional.empty();&lt;/p&gt;<br>
&lt;p&gt; } else {&lt;/p&gt;<br>
&lt;p&gt; return Optional.of(cliente);&lt;br&gt;<br>
}&lt;/p&gt;<br>
&lt;p&gt; }&lt;br&gt;<br>
}&lt;/p&gt;<br>
&lt;p&gt; Ahora la clase de repositorio hace uso de JPA pero apoyandose en tipos Optional de Java 8 de tal forma que cuando queramos acceder desde un cliente nos obligará a comprobar si existe un valor antes de imprimirlo por la pantalla.
&lt;/p&gt;<br>
&lt;p&gt;package repositorios;&lt;/p&gt;<br>
&lt;p&gt;import java.util.Optional;&lt;/p&gt;<br>
&lt;p&gt;import javax.persistence.EntityManager;&lt;br&gt;<br>
import javax.persistence.EntityManagerFactory;&lt;br&gt;<br>
import javax.persistence.Persistence;&lt;/p&gt;<br>
&lt;p&gt;import model.Cliente;&lt;br&gt;<br>
import repositorios.ejemplo2.ClienteRepository;&lt;/p&gt;<br>
&lt;p&gt;public class Principal2 {&lt;/p&gt;<br>
&lt;p&gt; public static void main(String[] args) {&lt;/p&gt;<br>
&lt;p&gt; EntityManagerFactory emf = Persistence.createEntityManagerFactory("jpa001");&lt;br&gt;<br>
EntityManager em = emf.createEntityManager();&lt;/p&gt;<br>
&lt;p&gt; ClienteRepository repositorio = new ClienteRepository(em);&lt;/p&gt;<br>
&lt;p&gt; Optional&amp;lt;Cliente&amp;gt; cliente=repositorio.buscarUno("1");&lt;/p&gt;<br>
&lt;p&gt; if (cliente.isPresent()) {&lt;br&gt;<br>
System.out.println(cliente.get().getNombre());&lt;br&gt;<br>
}&lt;/p&gt;<br>
&lt;p&gt; }&lt;/p&gt;<br>
&lt;p&gt;}&lt;/p&gt;<br>
&lt;p&gt; Aprendamos a usar Java Optional Repository como un refactor importante a la hora de construir nuestras clases clásicas de repositorio.
- Java Optional Stream y reference methods
- Java Optional ifPresent y como utilizarlo
- Java 8 Optional y NullPointerExceptions
- Java 8