Você está na página 1de 7

16/4/2015

PlayframeworkDocumentation

Laversin2.0dePlayyaestlista!Aydanosatraducirladocumentacindelatlimaversinysiguenuestroprogreso.

Principal

Aprende

Descargas

Comunidad

Cdigo

Ecosistema

Manuales,tutoriales&referencias

Mdulos

Acercade

Consulte
Contenidos

PersistenciaJPA
Playincluyeunconjuntodefunciones(helpers)muytilesparasimplificarlagestindetusentidades
JPA.
NotequesiemprepuedesvolverautilizarlaAPIpuradeJPAcuandoquieras.

Prximo:BibliotecasdePlay

Contenidos
1. Iniciandoelgestordeentidades
JPA
2. Obteniendoelgestorde
entidadesJPA
3. Gestindetransacciones

IniciandoelgestordeentidadesJPA
PlayiniciarautomticamenteelgestordeentidadesdeHibernatecuandoencuentreunaoms
clasesanotadasconlaanotacin @javax.persistence.Entity .Noobstante,asegratedequehayas
configuradocorrectamentelafuentededatosJDBCofallar.

4. Laclasedesoporte
play.db.jpa.Model
5. Manejopersonalizadodeidcon
GenericModel
6. Busncadoobjetos
BuscarporID
Traertodos
Buscarusandounaconsulta
simplificada

ObteniendoelgestordeentidadesJPA
UnavezquesehayainiciadoelgestordeentidadesJPA,puedesobtenerlodesdeelcdigodela
aplicacinusandoelhelperdeJPA.Porejemplo:
publicstaticindex(){
Queryquery=JPA.em().createQuery("select*fromArticle");
List<Article>articles=query.getResultList();
render(articles);
}

Buscarusandounaconsulta
JPQL
7. Contandoobjetos
8. Guardandolosficheros
cargadosconplay.db.jpa.Blob
9. Salvadoexplcito
10. Mssobreproblemasgenricos
detipos
11. Comentarios

Elijalaversin
1.2.4

Gestindetransacciones
Playgestionarautomticamentelastransaccionesport.Iniciarunatransaccinparacadapedido
HTTPylacerrarcuandoseenvelarespuestaHTTP.Sielcdigoarrojaunaexcepcin,la
transaccinharrollbackautomticamente.
Sinecesitasforzarunrollbackdelatransaccindesdeelcdigofuente,puedesusarelmtodo
JPA.setRollbackOnly() ,quelediceaJPAquenohagacommitdelatransaccinactual.

1.2.3

Buscar
Busquecongoogle

Libros

Tambinpuedesusaranotacionesapraespecificarcmohayquegestionarlastransacciones.
Sianotaselmtodoenelcontroladorcon @play.db.jpa.Transactional(readOnly=true) ,la
transaccinserdeslolectura.
SiquieresevitarquePlayarranquetransacciones,puedesanotarelmtodocon
@play.db.jpa.NoTransaction .
Paraevitarlastransaccionesparatodoslosmtodos,puedesanotarlaclaseControllercon
@play.db.jpa.NoTransaction .
Cuandoseusa @play.db.jpa.NoTransaction ,Playnoobtieneconexionesdelapool,loquemejorala
velocidaddelaaplicacin.

http://playdoces.appspot.com/documentation/1.2.4/jpa

1/7

16/4/2015

PlayframeworkDocumentation

Laclasedesoporteplay.db.jpa.Model
EstaeslaclasehelperprincipalparaJPA.SihacesqueunadetusentidadesJPAextiendalaclase
play.db.jpa.Model obtendrsmuchosmtodosdeayudaparasimplificarelaccesoJPA.

Porejemplo,veamosesteobjetodelmodeloPost:
@Entity
publicclassPostextendsModel{
publicStringtitle;
publicStringcontent;
publicDatepostDate;
@ManyToOne
publicAuthorauthor;
@OneToMany
publicList<Comment>comments;
}

Laclase play.db.jpa.Model automticamenteproporcionauncampo Longid autogenerado.


Creemosqueesbuenaideaengeneralusarel Longid autogeneradocomoclaveprimariaparalos
modelosJPA(laclaveprimariatcnica)ygestionarlaclaveprimariafuncionalusandootrocampo.
HemosusadoelhechodequePlayautomticamenteconsideraalosmiembrospublicdelaclase
Postcomoproperties.Asquenotenemosqueescribirlosmtodossetter/getterparaesteobjeto.

ManejopersonalizadodeidconGenericModel
Nadateobligaabasartusentidadesen play.db.jpa.Model .TusentidadesJPAtambinpueden
extenderlaclase play.db.jpa.GenericModel .Estoesloquetienesquehacersinoquieresusarel
Longid comoclaveprimariaparatuentidad.
Porejemplo,heaquelcdigoparaunaentidad User muysencilla.El id esunUUID,las
propiedades name y mail sonobligatoriasyusamosPlayValidationparaasegurarlasreglasde
negociosencillas.
@Entity
publicclassUserextendsGenericModel{
@Id
@GeneratedValue(generator="systemuuid")
@GenericGenerator(name="systemuuid",strategy="uuid")
publicStringid;
@Required
publicStringname;
@Required
@MaxSize(value=255,message="email.maxsize")
@play.data.validation.Email
publicStringmail;
}

Busncadoobjetos
Laclase play.db.jpa.Model teproporcionavariosmodosdeconsultarlainformacindelosmodelos.
Porejemplo:
BuscarporID
Elmodomssencillodeencontrarunobjeto.
PostaPost=Post.findById(5L);

http://playdoces.appspot.com/documentation/1.2.4/jpa

2/7

16/4/2015

PlayframeworkDocumentation

Traertodos
List<Post>posts=Post.findAll();

Estaeslaformamssencilladerecuperartodoslosposts,peropuedehacerselomismocon:
List<Post>posts=Post.all().fetch();

Loquepermitepaginarlosresultados:
//los100primerosposts
List<Post>posts=Post.all().fetch(100);

oincluso,

//hastaunmaximode100postsempezandoenel50
List<Post>posts=Post.all().from(50).fetch(100);

Buscarusandounaconsultasimplificada
Estotepermitecrearbuscadoresmuyexpresivos,peroslofuncionarnparaconsultassencillas.
Post.find("byTitle","Myfirstpost").fetch();
Post.find("byTitleLike","%hello%").fetch();
Post.find("byAuthorIsNull").fetch();
Post.find("byTitleLikeAndAuthor","%hello%",connectedUser).fetch();

Lasconsultassencillassiguenestasintaxis: [Property][Comparator]And? ,dondeComparatorpuede


seralgunodelossiguientes:
LessThan menorqueelvalordado
LessThanEquals menoroigualqueelvalordado
GreaterThan mayorqueunvalordado
GreaterThanEquals mayoroigualqueunvalordado
Like EquivalentealaexpresinlikedeSQL,exceptoquelapropiedadsiempreseconvertira

minsculas.
Ilike SimilaraLike,exceptoquenoessensitivoaminsculas,loqueindicaquetambinse

convertirelargumentoaminsculas.
Elike EquivalentealaexpresinlikedeSQL,sinconversin.
NotEqual Niegalaigualdad
Between Entredosvalores(tomadosargumentos)
IsNotNull Nonulo(norequiereargumento)
IsNull Esnulo(norequiereargumento)

BuscarusandounaconsultaJPQL
PuedesusarconsultasJPQL:
Post.find(
"selectpfromPostp,Commentc"+
"wherec.post=pandc.subjectlike?","%hop%"
);

oinclusounapartedeella:
Post.find("title","Myfirstpost").fetch();
Post.find("titlelike?","%hello%").fetch();
Post.find("authorisnull").fetch();

http://playdoces.appspot.com/documentation/1.2.4/jpa

3/7

16/4/2015

PlayframeworkDocumentation

Post.find("titlelike?andauthorisnull","%hello%").fetch();
Post.find("titlelike?andauthorisnullorderbypostDate","%hello%").fetch();

Inclusosepuedeespecificarsloelcomando orderby :
Post.find("orderbypostDatedesc").fetch();

Contandoobjetos
Puedesfcilmentecontarobjetos.
longpostCount=Post.count();

Ocontarusandounaconsulta:
longuserPostCount=Post.count("author=?",connectedUser);

Guardandolosficheroscargadosconplay.db.jpa.Blob
Puedesusareltipo play.db.jpa.Blob paraguardarlosficheroscargados(conupload)enelsistema
deficheros(noenlabasededatos).Enelservidor,Playguardalaimagenoficherocargadosenla
carpeta attachments/ ,dentrodelaaplicacin.Elnombredefichero(unUUID)yeltipoMIMEse
guardanenunatributodelabasededatoscuyotipoSQLes VARCHAR .
Elcasodeusobsicodecargar(upload),almacenaryservirunficheroesextremadamentefcilen
Play.EstoesporquePlayautomticamenteasignaunficherocargadodesdeunformularioHTMLal
modeloJPA,yporquePlayincluyemtodosquehacenqueservirdatosbinariosseatansencillocomo
sifuerantextoplano.Paraguardarlosficheroscargadosenelmodelo,aadeunapropiedaddeltipo
play.db.jpa.Blob .
importplay.db.jpa.Blob;
@Entity
publicclassUserextendsModel{

publicStringname;
publicBlobphoto;
}

Paracargarficheros,aadeunformularioatuplantilladelavista,yusauncontroldecargade
ficherosparalapropiedad Blob delmodelo:
#{form@addUser(),enctype:'multipart/formdata'}
<inputtype="file"name="user.photo">
<inputtype="submit"name="submit"value="Upload">
#{/form}

Luego,enelcontrolador,aadeunaaccinquesalvelocargadoenunnuevoobjetodelmodelo:
publicstaticvoidaddUser(Useruser){
user.save();
index();
}

EstecdigonoparecehacerotracosamsquesalvarlaentidadJPA,porquelacargadelficherola
gestionaautomticamentePlay.Primero,antesdearrancarelmtododeaccin,elficherocargado
sesalvaenunasubcarpetade tmp/uploads/ .Luego,cuandosesalvalaentidad,elficherosecopiaa
lacarpeta attachments/ ,conunUUIDcomonombredefichero.Finalmente,cuandolaaccinseha
completado,seborraelficherotemporal.
http://playdoces.appspot.com/documentation/1.2.4/jpa

4/7

16/4/2015

PlayframeworkDocumentation

Alcargarotroficheroparaelmismousuario,stesesalvarcomounnuevoficheroenelservidor,
cuyonombreesunnuevoUUID.Estosignificaqueelficherooriginalestarahorahurfano.Sino
tienesespacioilimitadoendisco,tendrsqueimplementartupropioesquemaparalimpiarestos
archivos,quizsconunjobasincrnico.
SielpedidoHTTPnoespecificaeltipoMIMEcorrectodelfichero,puedesasignarlomediantela
extensindelnombredefichero,comosedescribeensubiendoficherosdesdeelcontrolador.
Parasalvarlosfichersadjuntosenunacarpetadiferente,hayqueconfigurarattachments.path.
Paraservirunficheroguardado,sepasa Blob.get() almtodo renderBinary delControlador,como
seveenrespuestabinariadelcontrolador.

Salvadoexplcito
Hibernatemantieneunacachedeobjetosquehansidosolicitadosalabasededatos.Estosobjetos
sellamanobjetospersistentes,ylosonmientraselEntityManagerqueseuspararecuperarlosest
activo.EstoquieredecirqueloscambiosaestosObjetosentreloslmitesdeunatransaccinse
persistenautomticamentecuandosefinalizalatransaccin.EnelestndarJPA,estas
actualizacionessonimplcitasdentrodeloslmitesdelatransaccinnotienesquellamar
explcitamenteaningnmtodoparapersistirlosvalores.
Laprincipaldesventajadeesteenfoque,esquetenemosquegestionartodosnuestrosobjetos
manualmente.EnvezdedecirlealEntityManagerqueactualiceunobjeto(loqueseramsintuitivo),
tenemosquedecirlequobjetosNOhadeactualizar.Lohacemosllamandoalafuncin refresh() ,
queesencialmentehacerollbacksobreunasolaentidad.Hacemosestojustoantesdellamara
commitenlatransaccinocuandodecidimosqueelobjetonohadeseractualizado.
Esteesuncasodeusocomn,cuandoseesteditandounobjetopersistentedespusdeenviarel
formulario:
publicstaticvoidsave(Longid){
Useruser=User.findById(id);
user.edit("user",params.all());
validation.valid(user);
if(validation.hasErrors()){
//Tenemosquedesecharexplcitamentelasmodificacionesdelusuario...
user.refresh();
edit(id);
}
show(id);
}

Segnmiexperiencia,lamayoradelosdesarrolladoresnotienenpresenteestecomportamiento,y
olvidandesecharelestadodelobjetoencasodeerrores,asumiendoqueelobjetonosesalvarsin
unallamadaexplcitaa save() .
AsqueesoesexactamnteloquehemoscambiadoenPlay.Todoslosobjetospersistentesque
extiendenJPASupport/JPAModelnosesalvarnsinunallamadaexplcitaalmtodo save() .Asque
podramosreescribirelcdigoanteriordeestaforma:
publicstaticvoidsave(Longid){
Useruser=User.findById(id);
user.edit("user",params.all());
validation.valid(user);
if(validation.hasErrors()){
edit(id);
}else{
user.save();//salvadoexplicitoaqui
show(id);
}

http://playdoces.appspot.com/documentation/1.2.4/jpa

5/7

16/4/2015

PlayframeworkDocumentation

Estoesmuchomsintuitivo.Adems,comopuedesertediosollamara save() sobreungrafo


grandedeobjetos,lallamadaalmtodo save() sehaceautomticamenteencascada,grabando
tambinloscambiosenlasentidadescuyasrelacioneshayansidoanotadasconelatributo
cascade=CascadeType.ALL .

Mssobreproblemasgenricosdetipos
Laclase play.db.jpa.Model defineunconjuntodemtodosgenricos.Estosmtodosusanun
parmetrotypeparaespecificareltipoderetornodelmtodo.Cuandoseusanestosmtodos,eltipo
concretoautilizarcomovalorderetornosederivaapartirdelcontextodelainvocacinmediante
inferenciadetipos.
Porejemplo,elmtodo findAll sedefinecomo:
<T>List<T>findAll();

Yseusadeestaforma:
List<Post>posts=Post.findAll();

AquelcompiladorJavaresuelveeltiporealde T medianteelhechodequeasignaselresultadodel
mtodoaunList<Post>.LuegoTseresuelvecomodetipoPost.
Desafortunadamente,estonofuncionasielvalorderetornogenricodelmtodoseusacomo
parmetroparalainvocacinaotromtodooenunbucle,asqueelcdigosiguientefallarconun
errordelcompiladorquediceTypemismatch:cannotconvertfromelementtypeObjecttoPost
(Errordetipos:nopuedoconvertirdeelementodetipoObjectaPost):
for(Postp:Post.findAll()){
p.delete();
}

Porsupuesto,puederesolversemedianteunavariablelocaltemporal,comoen:
List<Post>posts=Post.findAll();//aquisfuncionalainferenciadetipos
for(Postp:posts){
p.delete();
}

Perohayunamaneramssimple.PuedesusarunacaractersticadeJavamuyprcticaperopoco
conocida,quehaceelcdigomscortoymslegiblealavez:
for(Postp:Post.<Post>findAll()){
p.delete();
}

EsimportanteadvertirquePlaynosoportaXA(commitsendosfases).Siusasdiferentes
configuracionesJPAenelmismopedidoHTTP,Playintentarhacercommitentantas
transaccionescomopueda.Sielcommitalaprimerabasededatostienexitoyelsegundo
commitaotrabasededatosfalla,elprimercommitnopodrdeshacerse(nopodrhacer
rollback).TenestoencuentacuandousesmltiplesconfiguracionesJPAenelmismorequest.

Prximospasos
AhoraveremosalgunasBibliotecasdePlay.

http://playdoces.appspot.com/documentation/1.2.4/jpa

6/7

16/4/2015

PlayframeworkDocumentation

Comentarios

0Comentarios

Playframeworksiteforspanishspeakingcommunity

Iniciarsesin
1

Compartir

Recomendar

Mejoresprimero

Comenzladiscusin...

Selprimeroencomentar.

Suscribirse

AgregDisqusatusitio

Privacidad

Aprende

Comunidad

Colabora

Download

Introduccin

@playframework

Cdigofuente

Versiones

Tuprimeraaplicacin

Grupodediscusin

Reportaerrores

Versionesnocturnas

Tutorial

PlanetPlay

Colaboradores

LicenciaApache2

Manuales

Cdigofuente

Integracincontinua

Play!esdesarrolladoporguillaumebortyzenexityDistribuidobajolicenciaapache2Hosteadoenplayapps.net

http://playdoces.appspot.com/documentation/1.2.4/jpa

7/7

Você também pode gostar