Your SlideShare is downloading. ×
Jpa Parte 2 Leonardo Torres Altez
Jpa Parte 2 Leonardo Torres Altez
Jpa Parte 2 Leonardo Torres Altez
Jpa Parte 2 Leonardo Torres Altez
Jpa Parte 2 Leonardo Torres Altez
Jpa Parte 2 Leonardo Torres Altez
Jpa Parte 2 Leonardo Torres Altez
Upcoming SlideShare
Loading in...5
×

Thanks for flagging this SlideShare!

Oops! An error has occurred.

×
Saving this for later? Get the SlideShare app to save on your phone or tablet. Read anywhere, anytime – even offline.
Text the download link to your phone
Standard text messaging rates apply

Jpa Parte 2 Leonardo Torres Altez

2,295

Published on

Tutorial de Toplink Jpa Parte 2

Tutorial de Toplink Jpa Parte 2

2 Comments
2 Likes
Statistics
Notes
  • muchas gracias, espero que sigas aportando con mas tutoriales que nos son de muchisima ayuda.
    gracias totales
       Reply 
    Are you sure you want to  Yes  No
    Your message goes here
  • muy buena la parte uno y esta parte dos tambien esta muy buena gracias

    por tu tutorial seguro a muchas personas como a mi nos ha servido de a mucho

    solo que les da pereza postearte o dejarte un comment

    bye
       Reply 
    Are you sure you want to  Yes  No
    Your message goes here
No Downloads
Views
Total Views
2,295
On Slideshare
0
From Embeds
0
Number of Embeds
1
Actions
Shares
0
Downloads
415
Comments
2
Likes
2
Embeds 0
No embeds

Report content
Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
No notes for slide

Transcript

  • 1. JAVA DEVELOPER - INSTRUCTOR - LEONARDO TORRES ALTEZ Advanced Mapping with JPA Nuevos requerimientos de Watermelon ... que tienen un “first JPA name”,un “last name” y “delivery addreses” . una “date of birth”, las Cada uno de esos “companies” tienen un “addresses” puede ser “name” un “contract usado el fin de semana name”, y un “number o por las noches. Voy of employees”. Esto me a implementar esta da la oportunidad de información añadiendo mapear una herencia “tags” a un “address”. Este articulo se va con JPA Para hacer todo esto , construir sobre el ejem- “Customers” tienen un voy a usar relaciones plo del primero : Una “home address” pero de tipo one-to-many y libreta de direcciones Watermelon también many-to-many de JPA. para una empresa ficti- necesita definir un La Figura muestra el cia de música llamada Watermelon. Para em- pezar , vamos a imagi- nar que Watermelon tiene algunos nuevos requerimientos , ahora hay dos tipos de “customers”: “individuals” y “companies”. “individuals” son un tipo de “customers” Herencia con JPA ? había sido manejada Como dije Waterme- también maneja una la en los EJBs de persis- lon ahora tiene dos relación a el Address. tencia , Gracias a JPA , tipos de “customers” : Ambos Individual and polimorfismo y heren- “individuals” y Company añaden atri- cia son posibles ahora “companies”. En el butos específicos en una aplicación Java modelo puedo descri- ( también un método EE y Java SE. Contraria- bir esto usando una para calcular la edad mente a las asociacio- clase abstracta Custo- del “individual” ). nes donde solo hay mer de la cual van a La herencia es una no- una forma de hacerlas , heredar las clases con la herencia el des- “Individual” y ción de los lenguajes arrollador tiene que “Company”. orientados a objetos en escoger entre diferen- “Customer” tiene un general y a Java en tes estrategias: ID , un “telephone particular . Pero guar- number” , un “email dar esta relación jerár- • address” , y un método quica en una estructura Una simple tabla por clase para validar “telephone relacional (base de heredada (SINGLE TABLE) es la estrategia por defecto, numbers” ( ver Anota- datos )es complicado . Esto significa que las tres clases Customer , Individual ciones Callback) , Esto Hasta ahora la herencia y Company usan una sola tabla ( ejemplo
  • 2. ADVANCED MAPPING WITH JPA Page 2 Lo mínimo necesario ... primary key. Esta opción provee Todos los atributos de estas tres soporte para relaciones polimórfi- clases son mapeados a una sola cas y esta es la opción que yo voy tabla. Esta forma es la mejor en a usar para mapear la herencia para términos de performance ,desde el sistema address book de Water- que una sola tabla es involucra- melon. da. De esta forma no se puede restringir que algunos atributos sean no nulos ( porque todas las Al escoger la estrategia de subclases son mapeadas en la mapeo, esta tiene que ser misma tabla ) echa una sola vez en la • Una tabla por entity class ( TA- entidad raíz (clase Custo- BLE_PER_CLASS) . Todas las mer), usando la anotación propiedades de una clase concreta, incluyendo propiedades que se @javax.persistence.Inheritan heredan son mapeadas a columnas de una tabla . En mi ejemplo yo ce . Esto es especificado en solo tengo una tabla t_company y la clase Customer como una t_individual . Los atributos de la clase base abstracta Customer sigue serán copiados en estas dos tablas. • <— Una tabla por clase (JOINED). En esta estrategia la clase raíz de la jerarquía (Customer) tanto como cada subclase es representada en una tabla separada . En el ejemplo de Watermelon tendré una tabla base común t_customer con un ID , telephone number , y un email adress. Las tablas de subclases ( t_company , t_individual ) serán unidas con la principal mediante su Estrategia JOINED ... @Entity @Table(name = quot;t_customerquot;) @Inheritance(strategy = InheritanceTy- Para trabajar , la para identificar que instancia decido nombrar la columna pe.JOINED) estrategia JOI- de la clase concreta es guarda- discriminadora DISC, y darle @DiscriminatorColumn(name = quot;DISCquot;, discri- minatorType = DiscriminatorType.STRING, NED ( también la da ( es un individual o un una longitud de 5 . Yo puedo length = 5) SINGLE TA- company que es guardado en hacer esto usando la anota- public abstract class Customer { BLE) necesita la tabla t_customer? ). Sin ción @Id información adi- ninguna anotación la codifica- @javax.persistence.Dicrimina @GeneratedValue cional : una co- ción por defecto va a crear torColumn . El contenido de private Long id; lumna discrimida- una columna llamada DTYPE esta columna puede ser custo- @Column(length = 15) dora . Esta colum- varchar(31) el cual su valor es mizada en cada clase concreta protected String telephone; @Column(name = quot;e_mailquot;) na , situada en la por defecto el nombre de la usando la anotación protected String email; tabla principal , clase concreta ( no abstracta ) @DicrimitarorValue. El valor // constructors, getters, setters habilita al persis- tiene que ser único y sirve } tence provider En el siguiente código , Yo para identificar una clase con- Estrategia JOINED ... creta . La codifi- cación por defec- to lo hará por defecto al nom- bre de la clase, Pero he decidido cambiar esto a “indiv” y “comp” . Ver tabla 1 .
  • 3. JAVA PERSISTENCE API Page 3 Unidad de Persistencia Vea que cada una de las tres entidades es mapeada a su propia tabla ( usando la anota- ción @Table ) .Como expli- que en el articulo previo , el EntityManager y las propieda- des seteadas en la unidad de persistencia automáticamente creara estas tablas. El resulta- do esta estrategia JOINED son los DDLs y los contraints de integridad entre las tres tablas, como se muestra en la Tabla 2. —> Métodos CRUD... Una vez que has escogido la datos. estrategia para mapear la herencia , tu puedes hacer los public void createCustomers() { // Gets an entity manager métodos CRUD de cualquiera EntityManagerFactory emf = Persistence.createEntityManagerFactory estas clases concretas usando (quot;watermelonPUquot;); el EntityManager tal como EntityManager em = emf.createEntityManager(); entidad . En el siguiente códi- EntityTransaction trans = em.getTransaction(); go yo creo una instancia de // Instantiates a company object Company y una clase Indivi- Company company = new Company(quot;Universalquot;, quot;Mr Universequot;, 50000, dual que persisto en la base de quot;+15488454quot;, quot;info@universal.comquot;); company.setHomeAddress(new Address(quot;World Streetquot;, quot;New Yorkquot;, quot;7448quot;, quot;UKquot;)); // Instantiates an individual object calendar.set(1940, 10, 9); Individual individual = new Individual(quot;Johnquot;, quot;Lennonquot;, quot;+441909quot;, quot;john@lenon.comquot;, calendar.getTime()); individual.setHomeAddress(new Address(quot;Abbey Roadquot;, quot;Londonquot;, quot;SW14quot;, quot;UKquot;)); // Persists both customers trans.begin(); em.persist(company); em.persist(individual); trans.commit(); // Closes the entity manager and the factory em.close(); emf.close(); }
  • 4. ADVANCED MAPPING WITH JPA Page 4 Hacer queries sobre un modelo jerárquico también es posible con JPQL . Yo puedo hacer queries en las clases concretas tanto como en la clase principal abstracta Y yo puedo usar los atributos de la clase principal en los queries. Por ejemplo, el mail address esta definido en la clase Customer , puedo usar este atributo en los queries envolviendo la clase customer también en la clase Individual y Company De acuerdo : no puedo usar los atributos de la clase hija para hacer queries en la clase padre.Por ejemplo , el atributo first name es justo definido en Individual . Yo no puedo usar este para hacer queries de customers y companies. En el adress book , las companies tienen un numero de employees . JPQL tiene un set de funcio- nes aritméticas que tu puede usar en un query. Yo también puedo usar restricciones en estos números aplicando funciones : menor que , mayor que , igual a . También obtener un rango de empleados
  • 5. Page 5 One to Many ... Ahora que ya esta mapeada la herencia. Voy a fijarme en el delivery addresses. En la Figura 1 una clase “Customer” tiene un “home address” ( mapeado en el articulo previo ) y cero o muchos delivery addresses. Esto es representado por una relación unidireccional , “one-to-many” entre “Customer” y “Address”. Hay dos diferentes estrategias que tu puedes usar para tener una relación “one-to-many” en una base de datos relacional . Lo primero es colocar un foreing key en la tabla representando “many” ( t_address) , apuntando a el primary key de la tabla representando el “one” ( t_customer ) . Lo segundo es usar una tercera tabla ( join_table ) para servir como un link entre estas dos, usando esta estrategia las relaciones “one-to-many” en JPA usan una tabla join. ( una tercera tabla ) El siguiente código muestra como manejar una relaciones de uno a muchos. Otra vez puedo dejar la codificación por de- fecto y a JPA mapear la relación por mi , pero decido usar anotaciones para customizar el mapeo. @Entity @Table(name = quot;t_customerquot;) @Inheritance(strategy = InheritanceType.JOINED) @DiscriminatorColumn(name = quot;DISCquot;, discriminatorType = DiscriminatorTy- pe.STRING, length = 5) public abstract class Customer { @Id @GeneratedValue private Long id; @Column(length = 15) protected String telephone; @Column(name = quot;e_mailquot;) protected String email; @OneToOne(fetch = FetchType.EAGER, cascade = {CascadeType.PERSIST, Cas- cadeType.REMOVE}) @JoinColumn(name = quot;home_address_fkquot;, nullable = false) private Address homeAddress; @OneToMany(fetch = FetchType.LAZY, cascade = CascadeType.ALL) @JoinTable(name = quot;t_delivery_addressesquot;, joinColumns = {@JoinColumn(name = quot;customer_fkquot;)}, inverseJoinColumns = {@JoinColumn(name = quot;address_fkquot;)}) private List deliveryAddresses = new ArrayList(); public void addDeliveryAddress(Address deliveryAddress) { deliveryAddresses.add(deliveryAddress); } // constructors, getters, setters } La anotación @javax.persistence.OneToMany es usada para relaciones “one-to-many” tiene los mismos atributos como @OneToOne ( ver el articulo previo) .Lo que yo estoy haciendo en el código que sigue es notificar a JPA el “lazy load” de el atributo “delivery address” ( atributo “fetch” ) y “cascade all ” de todos los eventos ( persist , remove , ..etc ) . Como mencione JPA mapea una relación “one-to-many” usando una join table. Para customizar el nombre y columnas de esta join table , Yo puedo usar la anotación @javax.persistence.JoinTable . De acuerdo a el código , la tabla join se llamara (t_delivery_address ) . Para cambiar los nombres de los foreing key , yo tengo que usar la anotación @JoinColumn. Con todas estas anotacio- nes , JPA va a crear y ade- cuar las tablas y los integrity constraints. La tabla 3 mues- tra los DDLs de las tres ta- blas involucradas en la rela- ción.
  • 6. ADVANCED MAPPING WITH JPA Page 6 Many to Many ... many” . En la base de datos , Para ayudar a clasificar los esta información será guarda- diferentes “addresses” que un da exactamente de la misma “customer” puede tener Wa- forma que las relaciones termelon quiere clasificarlos “one-to-many” : usando una ( tag ) . Un tag es una etiqueta tercera tabla que une los pri- ( un String) que puede ser mary keys. En la Tabla 4 tu añadido a una colección de encontraras la anotación addresses. “Tag” y “Address” @ManyToMany usada en tienen una relación bi– conjunción con @JoinTable y direccional , “many-to- @JoinColumn. El identificador ( @id ) de la clase “Tag” es un atributo de tipo String. El valor es seteado manualmente, por eso es que no hay una anotación @GeneratedValue. Ambas clases usan la anotación @ManyToMany significa que la relación es bidireccional . Cualquiera de estas clases podría definir los atributos de la tabla join ( @JoinTable) pero he decidido que la clase Address lo haga. La tabla join entre los “addresses” y “tags” es llamada t_address_tag . @OneToMany y @ManyToMany lidian con colecciones de objetos. Para hacer querys sobre colecciones , JPQL tiene un conjunto de keywords como EMPTY , que verifica si una colección esta vacía o no , o MEMBER OF que verifica si un objeto es un miembro de la colección . El código siguiente nos muestra como un objeto “address” y sus “tags” están relacionados. Tanto como definir algunos querys.
  • 7. JAVA PERSISTENCE API Page 7 One to One Relationship Tag tag1 = new Tag(quot;24/7quot;); Tag tag2 = new Tag(quot;working hoursquot;); Tag tag3 = new Tag(quot;week-endsquot;); Address address = new Address(quot;Central Side Parkquot;, quot;New Yorkquot;, quot;7845quot;, quot;USquot;); address.addTag(tag1); address.addTag(tag2); address.addTag(tag3); // Perists the address and its tags trans.begin(); em.persist(address); trans.commit(); Query query; List<Address> addresses; // Finds all the addresses either in London or New York query = em.createQuery(quot;SELECT a FROM Address a WHERE a.city IN ('London', 'New York') quot;); addresses = query.getResultList(); // Finds all the addresses that do not have a tag query = em.createQuery(quot;SELECT a FROM Address a WHERE a.tags IS EMPTYquot;); addresses = query.getResultList(); // Finds all the addresses that have at least one tag query = em.createQuery(quot;SELECT a FROM Address a WHERE a.tags IS NOT EMPTYquot;); addresses = query.getResultList(); // Finds all the addresses that have a quot;week-endsquot; tag query = em.createQuery(quot;SELECT a FROM Address a WHERE :param MEMBER OF a.tagsquot;); query.setParameter(quot;paramquot;, new Tag(quot;week-endsquot;)); addresses = query.getResultList();

×