= JPA com EclipseLink e Jersey
:index-group: JPA
:jbake-type: page
:jbake-status: published

Neste exemplo, um serviço da web é criado para armazenar e recuperar dados do banco de dados.
https://jersey.github.io/[Jersey] será usado para criar o serviço da web..
Para o banco de dados, o provedor JPA usado será https://www.eclipse.org/eclipselink/[EclipseLink].

O serviço da web irá armazenar e recuperar informações sobre pessoas:

[source,java]
----
@Entity
@XmlRootElement
@NamedQuery(name = "Person.findAll", query = "select p from Person p")
public class Person {

    @Id
    @GeneratedValue
    private long id;
    private String name;

    public long getId() {
        return id;
    }

    public void setId(long id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
----

Os dois serviços que nosso aplicativo oferece são: persistir uma pessoa, recuperando todas as pessoas do banco de dados:

[source,java]
----
@Singleton
@Lock(LockType.READ)
public class PersonDAO {

    @PersistenceContext
    private EntityManager em;

    public Person save(final String name) {
        final Person person = new Person();
        person.setName(name);
        em.persist(person);
        return person;
    }

    public List<Person> findAll() {
        return em.createNamedQuery("Person.findAll", Person.class).getResultList();
    }
----

A seguir, estamos prontos para expor como um serviço esta lógica de negócios:

[source,java]
----
@Path("/person")
@RequestScoped
public class PersonService {

    @Inject
    private PersonDAO dao;

    public PersonService() {
        System.out.println();
    }

    @GET
    @Path("/create/{name}")
    public Person create(@PathParam("name") final String name) {
        return dao.save(name);
    }

    @GET
    @Path("/all")
    public List<Person> list() {
        return dao.findAll();
    }
----

Agora que temos uma classe de serviço, definindo os recursos fornecidos pelo aplicativo, estendemos a classe `javax.ws.rs.core.Application` e adicionamos nosso `PersonService`:

[source,java]
----
public class JerseyApplication extends Application {

    @Override
    public Set<Class<?>> getClasses() {
        final Set<Class<?>> classes = new HashSet<Class<?>>();
        classes.add(PersonService.class);
        return classes;
    }
}
----

Há mais uma etapa a ser executada para configurar um servlet fornecido por Jersey.
Isso pode ser feito em `webapp/WEB-INF/web.xml`:

[source,xml]
----
<web-app xmlns="http://java.sun.com/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
         version="3.0">
  <servlet>
    <servlet-name>Jersey Web Application</servlet-name>
    <servlet-class>com.sun.jersey.spi.container.servlet.ServletContainer</servlet-class>
    <init-param>
      <param-name>javax.ws.rs.Application</param-name>
      <param-value>org.superbiz.service.JerseyApplication</param-value>
    </init-param>
    <load-on-startup>1</load-on-startup>
  </servlet>
  <servlet-mapping>
    <servlet-name>Jersey Web Application</servlet-name>
    <url-pattern>/*</url-pattern>
  </servlet-mapping>
</web-app>
----

O serviço da web está pronto para ser testado. Para isso, vamos escrever um teste de unidade usando http://arquillian.org/[Arquillian]:

[source,java]
----
@RunWith(Arquillian.class)
public class JerseyApplicationTest {

    @Deployment(testable = false)
    public static WebArchive createDeployment() {
        return ShrinkWrap.create(WebArchive.class, "jersey-application.war")
                .addPackage(JerseyApplication.class.getPackage())
                .addPackage(Person.class.getPackage())
                .addPackage(PersonDAO.class.getPackage())
                .addAsManifestResource(new FileAsset(new File("src/main/webapp/WEB-INF/web.xml")), "web.xml")
                .addAsManifestResource(new ClassLoaderAsset("META-INF/persistence.xml"), "persistence.xml")
                .addAsWebInfResource(EmptyAsset.INSTANCE, "beans.xml");
    }

    @ArquillianResource
    private URL webapp;

    @Test
    public void test() {
        get("person/create/TestPerson");

        String allPersons = get("person/all");

        assertTrue(allPersons.contains("<name>TestPerson</name>"));
    }

    private String get(String url) {
        final CloseableHttpClient client = HttpClients.custom().build();
        final HttpHost httpHost = new HttpHost(webapp.getHost(), webapp.getPort(), webapp.getProtocol());
        final HttpClientContext context = HttpClientContext.create();

        final HttpGet get = new HttpGet(webapp.toExternalForm() + url);
        CloseableHttpResponse response = null;
        try {
            response = client.execute(httpHost, get, context);
            return EntityUtils.toString(response.getEntity());
        } catch (final IOException e) {
            throw new IllegalStateException(e);
        } finally {
            try {
                IO.close(response);
            } catch (final IOException e) {
                // no-op
            }
        }
    }
}
----

Usamos o Arquillian para iniciar programaticamente um novo container de teste. Em um teste, uma pessoa é persistida e sua presença no banco de dados é verificada recuperando todas as entidades de pessoa.

Um exemplo completo pode ser encontrado https://github.com/apache/tomee/tree/master/examples/tomee-jersey-eclipselink[aqui].
É um projeto maven, e o teste pode ser executado com o comando `mvn clean install`.
