Você está na página 1de 9

Trabajando con JPA

Hasta el momento hemos estudiado cmo describir el conjunto de clases persistentes denuestraaplicacin,considerandosusatributos,claves primarias as como jerarquas de clases y relacione entre entidades. En esta seccin veremos cmo utilizar JPA para realizaroperacionescon estasclasespersistentes. En primer lugar, debemos describir algunos componentes de JPA, con los que debemos interactuar para realizar dichas operaciones.Estos componentesson: Unidadesdepersistencia. Contextosdepersistencia. Entitymanagers.

Unidades de persistencia.
Una unidad de persistencia define el conjunto de entities y su configuracin de mapeo que se asocia a un mismoorigendedatos.Encada aplicacinpuedeconfigurarsemsdeunaunidaddepersistencia. Las unidades de persistencia se definen en un archivo con combrepersistence.xml. Se debe definir al menos una unidad de persistencia.En aplicaciones JEE, se coloca en el directorio METAINF de un archivo .jar, ejbjar, .ear o .war; en aplicaciones JSE debe estar disponible enel classpath, dentro del directorio METAINF. En este xml se declara para, cada unidad de persistencia, sunombre(elcualutilizaremosdentrodela aplicacin), una descripcin, el proveedor de persistencia asociado, las propiedades de configuracin del mismo,eltipodetransaccin(JTAo Local),ycualquierotrainformacinrequeridaporelproveedordepersistencia. Acontinuacinvemosunejemplodeestearchivo:
<?xmlversion="1.0"encoding="UTF8"?> <persistenceversion="1.0" xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchemainstance" xsi:schemaLocation="http://java.sun.com/xml/ns/persistencehttp://java.sun.com/xml/ns/persistence/persistence_1_0.xsd"> <persistenceunitname="ar.com.fit.planner"> <provider>org.hibernate.ejb.HibernatePersistence</provider> <properties> <propertyname="hibernate.dialect"value="org.hibernate.dialect.MySQLDialect"/> <propertyname="hibernate.connection.driver_class"value="com.mysql.jdbc.Driver"/> <propertyname="hibernate.connection.username"value="fitplanner"/> <propertyname="hibernate.connection.password"value="fitplanner"/> <propertyname="hibernate.connection.url"value="jdbc:mysql://localhost:3306/fitplanner"></property>

open in browser PRO version

Are you a developer? Try out the HTML to PDF API

pdfcrowd.com

<!DescomentarlasiguientelineaparaqueHibernategenereelesquemadebasededatos> <!<propertyname="hibernate.hbm2ddl.auto"value="createdrop"/>> </properties> </persistenceunit> </persistence>

Contextos de persistencia.
Para cada unidaddepersistencia,elmotordeJPAestableceuncontextodepersistencia, que define el contextoenelcual"viven"yseadministran las instancias de las clases persistentes definidas en la unidad de persistencia. La definicinenlaespecificacindeJPAdice:es un conjuntode instanciasdeentidadesendondeparacadaidentidadpersistenteexisteunanicainstanciadeentityasociada. Todoelciclodevidadelosentitiesseproducedentrodeuncontextodepersistenciadado.

Ciclo de vida de los Entity Beans.


JPA define un conjuntodeestados que puede tener un objeto determinado en relacin a un contextodepersistenciaenparticular.Elciclo de vida de un Entity Bean es la definicin de las transiciones de un Entity Been entre los diferentes estados. A continuacinvemoseldiagramade transicindeestadosdeesteciclodevida:

open in browser PRO version

Are you a developer? Try out the HTML to PDF API

pdfcrowd.com

New:elentityexisteenmemoriaperonotieneasociadaunaidentidadpersistenteenlaBDouncontextodepersistencia. Managed:elentitytieneasociadounaidentidadyuncontextodepersistenciayelEntityManagermantienesincronizadosuestadoal momentodecommitdelatransaccinobienalllamaralmtodoflush(). Detached:elentitynoesadministradoporelEntityManager,noestasociadoaningncontextodepersistencia.Unaentidadadministrada (managed)sedesvinculaalfinalizarlavidadelcontextodepersistencia(scope,sesin)ocuandoseserializa(porej.alserenviadoentre capas) Removed:elentitypuedeestarasociadoalcontextodepersistenciaperoestmarcadoparaeliminacinalmomentodefinalizarla transaccin. Persisted:elentitybeanexisteenlabasededatos,peronohasidocargadoenmemoria.

Entity Manager
ElEntityManager es es la fachada de servicios de JPA. Cada Entity Manager permite acceder a un contexto de persistencia, ycadacontextode persistencia se refiere a una unidad de persistencia. Los servicios del Entity Manager operan sobre entidades. Todo cliente que quiera interactuar con entidades persistentes debe primero obtener una instancia del Entity Manager. Provee operaciones debsqueda,actualizacin,borradoy persistenciadenuevasentidades.

open in browser PRO version

Are you a developer? Try out the HTML to PDF API

pdfcrowd.com

Obteniendo un Entity Manager


El Entity Manager es un objeto que implementa la interfaz javax.persistence.EntityManager. Existen diferentes formas de obtener dicha instancia, dependiendo del tipo de aplicacin. En entornos JEE el Entity Manager es administrado por el contenedoryseobtienede2formasposibles: inyeccinolook upJNDI.EnentornosJSEelEntityManagerseobtieneatravsdelainterfazjavax.persistence.EntityManagerFactory.

Obteniendo un Entity Manager en aplicaciones JSE.


Intentaremos realizar algunas operaciones con las clases persistentes que hemos definido hasta el momento. Dado que an no hemosarmadola aplicacin JEE completa, haremos una pequea clase de prueba, en la que accederemos al Entity Manager utilizando lainterfaz javax.persistence.EntityManagerFactory. En primer lugar, debemos obtener una instancia de la interfaz EntityManagerFactory, para lo cual se utiliza la clasebootstrap javax.persistence.Persistence. Esta clase se encarga de examinar el archivo persistence.xml, y entregarunainstanciadeEntityManagerFactory asociadaaunaunidaddepersistenciadeterminada.Veamosunejemplo:
EntityManagerFactoryemf=javax.persistence.Persistence.createEntityManagerFactory("ar.com.fit.planner");

El mtodo javax.persistence.Persistence.createEntityManagerFactory(String) recibe como parmetro el nombre de una unidaddepersistencia definidaenelarchivopersistence.xml.UnavezquetenemoslainstanciadeEntityManagerFactory,podemospedirleelEntityManager:


EntityManagerem=emf.createEntityManager();

YapodemoscomenzaraoperarconnuestrosEntityBeans.

Persistiendo objetos.
Enesteejemplovemoscmocrearunobjetoutilizandounaclasepersistente,ycmopersistirloconelEntityManager:
em.getTransaction().begin(); Clientecliente1=newClienteUnipersonal("Mario","Lpez"); em.persist(cliente1); em.getTransaction().commit();

Transacciones usando JPA en aplicaciones JSE.


open in browser PRO version
Are you a developer? Try out the HTML to PDF API

pdfcrowd.com

Si analizamos el cdigo del ejemplo, vemos que la operacin em.persist(fit) est encerrada entre otras dos: em.getTransaction().begin() y em.getTransaction().commit(). Dado que no estamos en un ambiente JEE, debemos administrar las transacciones manualmente. Esto implica especificarle alEntityManager cundo debe comenzar unatransaccin,ycundoterminarla.ElEntityManagerrealizarningncambioenlabasededatoshastaquenohayamos realizado un commit de la transaccin. En aplicaciones JEE, por supuesto,lastransaccionessonadministradasporelcontenedor,porloqueesta tareanoesnecesaria.

Operaciones bsicas.
Persist.
La operacin EntityManager.persist(Object) recibe como parmetro un objeto de una clase anotada con @Entityylopersisteenlabasededatos. Persiste, tambin, todos los objetos relacionados, cuya relacin haya sido anotada conCascadeType.PERSISToCascadeType.ALL.Porlotanto, conunanicaoperacinJPApuedepersistirtodounrboldeobjetos,segnlasdefinicionesdelasrelaciones. Las operaciones de persistencia se traducen, en algn momento, en sentencias INSERT en labasededatos.Elproveedordepersistenciaelige cundo ejecutar estas sentencias. Hibernate, por ejemplo, las ejecuta al realizar el commit de la transaccin. En una aplicacin JSE,estoocurre cuandosellamaexplcitamentealmtodoentityManager.getTransaction().commit(). DespusderealizarestaoperacinsobreunEntityBean,elobjetoquedaenestadoManaged.

Remove.
La operacin EntityManager.remove(Object) recibeunobjetodeunaclaseanotadacon@Entity,yloborradelabasededatos.Despusderealizar estaoperacin,elobjetoquedaenestadoRemoved.Alterminarlatransaccin,seejecutaunasentenciaDELETE.

Refresh.
La operacin EntityManager.refresh(Object) recibe un objeto de una clase anotada con @Entity ysincronizasuestadoconeldelabasededatos. Es decir, actualiza el objeto obteniendo los valores de susatributosyrelacionesdelabasededatos.SeejecutaunasentenciaSELECT.Despus deejecutarestaoperacin,elobjetoquedaenestadoManaged.

Merge.
open in browser PRO version
Are you a developer? Try out the HTML to PDF API

pdfcrowd.com

La operacin EntityManager.merge(Object) sincroniza el estado de un objeto en la base de datos. Al terminar la transaccin,seejecutauna sentenciaUPDATE.ElobjetonodebeestarenestadoRemoved.Despusdeejecutarestaoperacin,elobjetoquedaenestadoManaged.

Bsquedas simples.
La forma ms sencilla de buscar un Entity Bean es utilizar elmtodofind(Class,Object)delainterfazEntityManager.Estemtodopermitebuscar unEntityporsuclaveprimaria. Parabuscarunaclienteporejemplo,podramosusarelsiguientecdigo:
Clientecliente=entityManager.find(Cliente.class,newLong(1));

ElprimerparmetrodelmtodofindeslaclasedelEntityquedeseamosbuscar.Elsegundoparmetro,laclaveprimariadelEntity.Laclaseque pasemoscomoparmetrodebeserunaanotadacon@Entity;nopodemosusar,porejemplo,unaclaseanotadacon@MappedSuperclass.Enel ejemplovemosqueestamosaccediendoaunclientedemanerapolifrmica;esdecir,noconocemosapriorisielclienteescorporativoo unipersonal.DadoquelaclaseClienteextiendeaPersona,tambinpodramoshaberhecho:


Persona=entityManager.find(Persona.class,newLong(1));

Esta bsqueda debera devolver el mismo Entity, dado que toda la jerarqua de clases que extiende a Persona comparte la misma clave primaria. Perodadoqueestamoshaciendounabsquedapolimrfica,nopodemossaber,apriori,silaconsultadevolverunClienteounEmpleado.

Bsquedas con JP QL.


JPA ofrece una API para realizar tanto consultas como operaciones masivas sobre Entity Beans (actualizaciones y eliminaciones).EstaAPI involucra,bsicamente,trescomponentes: MtodosdeconsultadelEntityManager. Lainterfazjavax.persistence.Query. EllenguajeJPQL(JavaPersistenceQueryLanguage). Enestaseccinanalizaremoslascaractersticasbsicasdecadaunodeestoscomponentes.

JPQL
Seguramente,ennuestraaplicacindeberemosrealizarbsquedasmscomplejasquesolamenteporlaclaveprimariadeunobjeto;porejemplo: open in browser PRO version Are you a developer? Try out the HTML to PDF API pdfcrowd.com

Obtenertodaslascompaasconmsdeunempleado. Obtenertodoslosempleadospertenecientesalascompaasquetenganmsdetresproyectos. Para estetipodeconsultas,JPAdefineJPQL3. Es un lenguaje que permitecreartrestiposdesentencias(consulta,actualizacinyeliminacin),y que opera sobre Entity Beans. Presenta una sintaxis similar a SQL, pero no est orientado a un modelorelacional(basadoentablasycolumnas) sinoaunmodelodeobjetos(objetosyatributos).Permitealprogramadorindependizarsedelabasededatosydelesquemarelacional. Comenzaremos viendo algunos ejemplos de consultas sencillas utilizando este lenguaje. Nuestro primer ejemplo es una consultaquenospermite obtenertodaslascompaasalmacenadas:
SELECTcFROMCompaniac

VemosquelasentenciaessimilaraunaconsulaSQL,conalgunasdiferencias: Laclusulafromnoserefiereaunatabla,sinoaunaclase(enestecaso,laclaseCompany). Elresultadodelaconsultanoesunconjuntodecolumnas,sinounobjeto,unEntityBean. Paraejecutarestaconsulta,debemosutilizaelEntityManagerenconjuntoconlainterfazjavax.persistence.Query:


Queryq=entityManager.createQuery("SELECTcFROMCompaniac"); Listcompanias=q.getListResult();

El proveedor de persistencia utiliza las anotaciones de la clase Compania para traducir la consulta JPQL en unaconsultaSQL.Porejemplo,la traduccindelaconsultaanteriorpodrasersimilara:
SELECT*FROMcompanias

AtravsdelEntityManger,podemosejecutardostiposdeconsultas:dinmicasyestticas.

Consultas dinmicas
Son aquellas cosultas que no estn definidas de manera fija, sino queseconstruyenentiempodeejecucin.Despusdeconstruirlaconsulta,se utiliza el mtodo EntityManager.createQuery(String) para obtener el objeto Query que la representa. El anterioresunejemplodeunaconsulta dinmica.CadaejecucindelmtodoEntityManager.createQuerycreaunanuevainstanciadejavax.persistence.Query. Estetipodeconsultasnoestpensadoparaserreutilizado.

open in browser PRO version

Are you a developer? Try out the HTML to PDF API

pdfcrowd.com

Consultas estticas
Son consultascuyadefinicinnovaraentiempodeejecucin.Estnpensadasparaserreutilizadasmuchasveces.Selaspuededefinirenlaclase de un Entity Bean. Favorecen la mantenibilidad ylegibilidaddelcdigo,ypuedenaumentarlaperformanceyaquesepreparanunasolavezyluego sereusancadavezquesonllamados. Para definirlas enlaclasedeunEntityBean,seutilizanlasanotaciones@NamedQueryy@NamedQueries. Para definirunanicaconsultaenla clasedeunEntityBean:
@Entity @Table(name="companias") @NamedQuery(name="buscarCompanias", query="SELECT c FROM Compania c") publicclassCompania{ ///... }

Paradefinirmltiplesconsultasenlamismaclase:
@Entity @Table(name="companias") @NamedQueries(value={ @NamedQuery(name="buscarCompanias", query="SELECT c FROM Compania c"), @NamedQuery(name="buscarCompaniasOrdenado", query="SELECT c FROM Compania c ORDER BY c.nombre")} ) publicclassCompania{ //... }

Para ejecutarlas, debemosutilizarelmtodoEntityManager.createNamedQuery(String),pasandocomoparmetroelnombredelaconsulta,definido enelatributonamedelaanotacin@NamedQuerycorrespondiente:


Queryq=entityManager.createNamedQuery("buscarCompanias"); Listcompanies=q.getResultList();

Dentrodelaunaunidaddepersistencia,nopuedehaberdosconsultasestticasconelmismonombre. Comoreglageneral,espreferibleelusodeconsultasestticasporsobrelasconsultasdinmicas,dadoqueofrecenunagananciaenperformance.

open in browser PRO version

Are you a developer? Try out the HTML to PDF API

pdfcrowd.com

Parametrizacin de consultas
Unaconsultapuedeparametrizarsemediante2tiposdeparmetros: Posicionales Pornombre Parautilizarparmetrosposicionales,elparmetrodebeindicarseenlaclusulawheredelaconsultaconelprefijo?yacontinuacinelnmerodel parmetro:
SELECTcFROMCompaniacWHEREc.nombre=?1

Luego,alejecutarla,seestableceelvalordelparmetrosegnsuposicin:
Queryq=entityManager.createQuery("SELECTcFROMCompaniacWHEREc.nombre=?1"); q.setParameter(1,"FITSC"); Companiac=q.getSingleResult();

Para utilizar parmetros por nombre, el parmetro debe indicarseenlaclusulawheredelaconsultaconelprefijo: y a continuacinelnombredel parmetro:
SELECTcFROMCompaniacWHEREc.nombre=:nombreDeLaCompania

Luego,alejecutarla,seestableceelvalordelparmetrosegnsunombre:
Queryq=entityManager.createQuery("SELECTcFROMCompaniacWHEREc.nombre=:nombreDeLaCompania"); q.setParameter("nombreDeLaCompania","FITSC"); Companyc=q.getSingleResult();

Ambosestilosdeparametrizacinpuedenusarseenconsultasestticascomodinmicas,indistintamente.

open in browser PRO version

Are you a developer? Try out the HTML to PDF API

pdfcrowd.com

Você também pode gostar