ORM JPA

5,165 views

Published on

Presentation given at the minor EAD, ICA, HAN University

0 Comments
3 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total views
5,165
On SlideShare
0
From Embeds
0
Number of Embeds
18
Actions
Shares
0
Downloads
0
Comments
0
Likes
3
Embeds 0
No embeds

No notes for slide
  • ORM JPA

    1. 1. Object/Relational Mapping Java Persistence API Minor Enterprise Application Development
    2. 2. Understand ORM to use it <ul><li>” The effective use of ORM technology in all but the simplest of enterprise environments requires understanding and configuring how the mediation between relational data and objects is performed” </li></ul><ul><li>Linda DeMichiel, Lead Architect EJB, Sun </li></ul>
    3. 3. “ Modern” ORM Solutions <ul><li>Transparent Persistence (POJO/JavaBeans) </li></ul><ul><li>Persistent/transient instances </li></ul><ul><li>Automatic Dirty Checking </li></ul><ul><li>Lazy Fetching </li></ul><ul><li>Outer Join Fetching </li></ul><ul><li>Runtime SQL Generation </li></ul><ul><li>Three Basic Inheritance Mapping Strategies </li></ul>
    4. 4. Why? <ul><li>Natural programming model </li></ul><ul><li>Minimize LOC </li></ul><ul><li>Code can be run and/or tested outside the “container” </li></ul><ul><li>Classes may be reused in “nonpersistent” context </li></ul><ul><li>Minimize database access with smart fetching strategies </li></ul><ul><li>Opportunities for aggressive caching </li></ul><ul><li>Structural mapping more robust when object/data model changes </li></ul>
    5. 5. Entity Beans? <ul><li>Transparent Persistence  </li></ul><ul><li>Persistent/transient instances  </li></ul><ul><li>Automatic Dirty Checking  </li></ul><ul><li>Lazy Fetching  </li></ul><ul><li>Outer Join Fetching  </li></ul><ul><li>Runtime SQL Generation  </li></ul><ul><li>Three Basic Inheritance Mapping Strategies  </li></ul>
    6. 6. What do RDBs do well? <ul><li>Work with large amounts of data </li></ul><ul><ul><li>Searching, sorting </li></ul></ul><ul><li>Work with sets of data </li></ul><ul><ul><li>Joining, aggregating </li></ul></ul><ul><li>Sharing </li></ul><ul><ul><li>Concurrency (Transactions) </li></ul></ul><ul><ul><li>Many applications </li></ul></ul><ul><li>Integrity </li></ul><ul><ul><li>Constraints </li></ul></ul><ul><ul><li>Transaction isolation </li></ul></ul>
    7. 7. What do RDBs do badly? <ul><li>Modeling </li></ul><ul><ul><li>No polymorphism </li></ul></ul><ul><ul><li>Fine grained models are difficult </li></ul></ul><ul><li>Business logic </li></ul><ul><ul><li>Stored procedures kinda suck </li></ul></ul><ul><li>Distribution </li></ul><ul><ul><li>(arguable, I suppose) </li></ul></ul>
    8. 8. Data is important <ul><li>Even so, the relational model is important… </li></ul><ul><li>The data will be around much longer than the Java application! </li></ul>
    9. 9. The Goal <ul><li>Take advantage of those things that relational databases do well </li></ul><ul><li>Without leaving the language of objects / classes </li></ul>
    10. 10. The Real Goal <ul><li>Do less work </li></ul><ul><li>Happy DBA </li></ul>
    11. 11. Impedance Mismatch <ul><li>Identity </li></ul><ul><li>Granularity </li></ul><ul><li>Object navigation </li></ul><ul><li>Subtypes </li></ul><ul><li>Polymorphic associations </li></ul>
    12. 12. Inheritance <ul><li>Table per </li></ul><ul><li>concrete class </li></ul>B a1 C * id a1 * id A * id a1 b1 b1 c1 c1 A * id B * id C * id a1 b1 c1 Table per class hierarchy Table per class A a1 B b1 C c1
    13. 13. Entity <ul><li>Lightweight persistent domain object – the thing you persist </li></ul><ul><li>Restrictions </li></ul><ul><ul><li>must have a public or protected no-arg constructor </li></ul></ul><ul><ul><li>cannot be final </li></ul></ul><ul><ul><li>cannot have final methods or final instance variables that are to be persisted </li></ul></ul><ul><ul><li>can be abstract or concrete class </li></ul></ul><ul><ul><li>must have a primary key </li></ul></ul>
    14. 14. Entity Relationships <ul><li>Defined by relationships in the database schema </li></ul><ul><ul><li>ManyToOne </li></ul></ul><ul><ul><li>OneToOne </li></ul></ul><ul><ul><li>OneToMany </li></ul></ul><ul><ul><li>ManyToMany </li></ul></ul>
    15. 15. Entity Manager <ul><li>The JPA interface for working with a persistence context </li></ul><ul><li>Core methods a JPA application will use </li></ul><ul><ul><li>persist </li></ul></ul><ul><ul><li>remove </li></ul></ul><ul><ul><li>find </li></ul></ul><ul><ul><li>createQuery </li></ul></ul><ul><ul><li>close </li></ul></ul>
    16. 16. Annotations Overview <ul><li>Core </li></ul><ul><ul><li>@Entity </li></ul></ul><ul><ul><li>@Table </li></ul></ul><ul><ul><li>@Id </li></ul></ul><ul><ul><li>@Basic </li></ul></ul><ul><ul><li>@Column </li></ul></ul><ul><ul><li>@Transient </li></ul></ul><ul><ul><li>@Enumerated </li></ul></ul><ul><ul><li>@Temporal </li></ul></ul><ul><ul><li>@Type </li></ul></ul><ul><li>Relationships </li></ul><ul><ul><li>@ManyToOne </li></ul></ul><ul><ul><li>@OneToOne </li></ul></ul><ul><ul><li>@OneToMany </li></ul></ul><ul><ul><li>@JoinColumn </li></ul></ul><ul><li>Inheritance </li></ul><ul><ul><li>@MappedSuperclass </li></ul></ul><ul><ul><li>@Inheritance </li></ul></ul><ul><ul><li>@DiscriminatorColumn </li></ul></ul><ul><ul><li>@DiscriminatorValue </li></ul></ul>
    17. 17. @Entity / @Table @Entity @Table(name=“PROSPECT”) public class Prospect extends Persistent { ... public Prospect() { ... } } MAUI.PROSPECT PROSPECT_ID NUMBER(18) LAST_UPD_BY NUMBER(18) LAST_UP_TS TIMESTAMP(9) STUDENT_ID NUMBER(18) ... ...
    18. 18. @Id <ul><li>Every entity needs a primary key </li></ul><ul><li>... </li></ul><ul><li>public abstract class Persistent { </li></ul><ul><li>@Id </li></ul><ul><li>Long id; </li></ul><ul><li>... </li></ul><ul><li>} </li></ul>
    19. 19. @Basic / @Column <ul><li>... </li></ul><ul><li>public class Prospect extends Persistent { </li></ul><ul><li>@Basic </li></ul><ul><li>@Column(name = &quot;HS_SELF_REPORTED_CLASS_SIZE&quot;) </li></ul><ul><li>private Integer selfReportedClassSize; </li></ul><ul><li>@Basic </li></ul><ul><li>@Column(name = &quot;HS_ANTICIPATED_YR_GRAD&quot;) </li></ul><ul><li>private String anticipatedHighSchoolGraduationYear; </li></ul><ul><li>... </li></ul><ul><li>} </li></ul>MAUI.PROSPECT PROSPECT_ID NUMBER(18) ... ... HS_SELF_REPORTED_CLASS_SIZE NUMBER(5) HS_ANTICIPATED_YR_GRAD CHAR(4) ... ...
    20. 20. @Transient <ul><li>Indicates fields that should not be persisted </li></ul><ul><li>But it could be used for computed/derived data based on the persistent fields of the object </li></ul>
    21. 21. @Enumerated <ul><li>public enum ProspectStatusEnum { </li></ul><ul><li>PROSPECT(&quot;Prospect&quot;), </li></ul><ul><li>PROSPECT_INACTIVE( &quot;Prospect Inactive&quot;), </li></ul><ul><li>PROSPECT_APPLIED( &quot;Prospect Applied&quot;); </li></ul><ul><li>private String label; </li></ul><ul><li>ProspectStatusEnum(String label) { </li></ul><ul><li> this.label = label; </li></ul><ul><li>} </li></ul><ul><li>public String toString() { </li></ul><ul><li> return this.label; </li></ul><ul><li>} </li></ul><ul><li>} </li></ul>
    22. 22. @Enumerated ... public class Prospect extends Persistent { ... @Enumerated(EnumType.STRING) @Column(name = &quot;PRSP_STATUS_EN&quot;) ProspectStatusEnum prospectStatusEnum; ... } MAUI.PROSPECT ... ... PRSP_STATUS_EN VARCHAR(25) ... ...
    23. 23. @ManyToOne ... public class Prospect extends Persistent { @ManyToOne() @JoinColumn(name = &quot;PURGE_SESSION_INFO_ID&quot;) private Session purgeSession; ... } @Entity @Table(name = &quot;MAUI.SESSION_INFO&quot;) public class Session extends Persistent { ... } MAUI.SESSION_INFO SESSION_INFO_ID NUMBER(18) ... ... MAUI.PROSPECT PROSPECT_ID NUMBER(18) PK ... ... PURGE_SESSION_INFO_ID NUMBER(18) FK
    24. 24. @OneToOne <ul><li>public class Prospect extends Persistent { </li></ul><ul><li>@OneToOne() </li></ul><ul><li>@JoinColumn(name = &quot;STUDENT_ID&quot;) </li></ul><ul><li>private Student student; </li></ul><ul><li>... </li></ul><ul><li>} </li></ul><ul><li>@Entity </li></ul><ul><li>@Table(name = &quot;MAUI.STUDENT&quot;) </li></ul><ul><li>public class Student extends Persistent { ... } </li></ul>MAUI.STUDENT STUDENT_ID NUMBER(18) PK ... ... MAUI.PROSPECT PROSPECT_ID NUMBER(18) PK ... ... STUDENT_ID NUMBER(18) FK UNIQUE NOT NULL
    25. 25. @OneToMany public class Prospect extends Persistent { ... @OneToMany(mappedBy = &quot;prospect”) private Set<ProspectComment> prospectComments; } @Entity public class ProspectComment extends Persistent { ... @ManyToOne() @JoinColumn(name = &quot;PROSPECT_ID&quot;) private Prospect prospect; } MAUI.PRSP_COMMENT PRSP_COMMENT_ID NUMBER(18) PK PROSPECT_ID NUMBER(18) FK NOT NULL ... ... MAUI.PROSPECT PROSPECT_ID NUMBER(18) PK ... ...
    26. 26. @MappedSuperclass <ul><li>@MappedSuperclass </li></ul><ul><li>public abstract class Persistent { </li></ul><ul><li>... </li></ul><ul><li>@Id </li></ul><ul><li>private Long id; </li></ul><ul><li>@Temporal </li></ul><ul><li>@Column(name = “LAST_UPD_TS”) </li></ul><ul><li>private Date lastUpdatedTimestamp; </li></ul><ul><li>} </li></ul>
    27. 27. @Inheritance <ul><li>Three strategies </li></ul><ul><ul><li>Single Table Per Class Hierarchy </li></ul></ul><ul><ul><ul><li>SINGLE_TABLE </li></ul></ul></ul><ul><ul><li>Joined Subclass </li></ul></ul><ul><ul><ul><li>JOINED </li></ul></ul></ul><ul><ul><li>Table Per Concrete Class </li></ul></ul><ul><ul><ul><li>TABLE_PER_CLASS </li></ul></ul></ul>
    28. 28. Bootstrapping Configuration <ul><li>One XML file: META-INF/persistence.xml </li></ul><ul><ul><li><persistence> </li></ul></ul><ul><ul><li><persistence-unit name=&quot;OrderManagement&quot;> </li></ul></ul><ul><ul><li><provider> </li></ul></ul><ul><ul><li>org.apache.openjpa.persistence.PersistenceProviderImpl </li></ul></ul><ul><ul><li></provider> </li></ul></ul><ul><ul><li><jta-data-source>jdbc/MyOrderDB</jta-data-source> </li></ul></ul><ul><ul><li><mapping-file>ormap.xml</mapping-file> </li></ul></ul><ul><ul><li><class>com.widgets.Order</class> </li></ul></ul><ul><ul><li><class>com.widgets.Customer</class> </li></ul></ul><ul><ul><li></persistence-unit> </li></ul></ul><ul><ul><li></persistence> </li></ul></ul><ul><li>Persistence provider is automatically located if not specified in XML </li></ul><ul><ul><li>No JDBC-style provider bootstrapping required </li></ul></ul>
    29. 29. @FetchType defaults <ul><li>@Entity </li></ul><ul><li>public class Employee { </li></ul><ul><li>@Id private long pk; </li></ul><ul><li>private String name; </li></ul><ul><li>@ManyToOne private Employee manager; </li></ul><ul><li>@OneToOne private Address primaryAddress; </li></ul><ul><li>@ManyToOne private Department department; </li></ul><ul><li>} </li></ul>
    30. 30. @FetchType defaults <ul><li>@Entity </li></ul><ul><li>public class Employee { </li></ul><ul><li>@Id private long pk; </li></ul><ul><li>private String name; </li></ul><ul><li>@ManyToOne (fetch=LAZY) private Employee manager; </li></ul><ul><li>@OneToOne (fetch=LAZY) private Address </li></ul><ul><li>primaryAddress; </li></ul><ul><li>@ManyToOne (fetch=LAZY) private Department </li></ul><ul><li>department; </li></ul><ul><li>} </li></ul>
    31. 31. <T> <ul><li>Java 5 generics are great </li></ul><ul><li>Reduces the amount of syntactic noise in source files </li></ul><ul><ul><li>Employee emp = em.find(Employee.class, 17); </li></ul></ul><ul><ul><li>public Quote updateQuote(Quote quoteDTO) { </li></ul></ul><ul><ul><li>Quote q = em.merge(quoteDTO); </li></ul></ul><ul><ul><li>} </li></ul></ul>
    32. 32. Outside-the-container APIs <ul><li>EntityManagerFactory emf = </li></ul><ul><li>Persistence.createEntityManagerFactory(“OrderManagement”); </li></ul><ul><li>EntityManager em = </li></ul><ul><li>emf.createEntityManager(); </li></ul><ul><li>em.getTransaction ().begin(); </li></ul><ul><li>try { </li></ul><ul><li>Collection<Customer> customers = </li></ul><ul><li>loadCustomersFromFile( </li></ul><ul><li>new File(“nightly-upload.csv”)); </li></ul><ul><li>for (Customer customer : customers) </li></ul><ul><li>em.persist(customer); </li></ul><ul><li>em.getTransaction(). commit (); </li></ul><ul><li>} </li></ul><ul><li>finally { </li></ul><ul><li>if (em.getTransaction().isActive()) </li></ul><ul><li>em.getTransaction().rollback(); </li></ul><ul><li>} </li></ul><ul><li>em.close(); </li></ul><ul><li>emf.close(); </li></ul>
    33. 33. Dynamic queries! <ul><li>Query q = em.createQuery ( “ select c from Customer c </li></ul><ul><li>where c.firstName = :fname order by c.lastName ” ); </li></ul><ul><li>q.setParameter( “ fname ” , “ Joe ” ); </li></ul><ul><li>List<Customer> customers = (List<Customer>) q.getResultList(); </li></ul>
    34. 34. Ranged queries <ul><li>All databases support some sort of in-DB limiting of records </li></ul><ul><li>All databases provide this support in very different ways </li></ul><ul><li>JPAQL supports ranging directly in the APIs </li></ul><ul><li>Query q = em.createQuery( “ select c from Customer c </li></ul><ul><li>where c.firstName = :fname order by c.lastName ” ); </li></ul><ul><li>q.setParameter( “ fname ” , “ Joe ” ); </li></ul><ul><li>q.setFirstResult(20); </li></ul><ul><li>q.setMaxResults(10); </li></ul><ul><li>List<Customer> customers = (List<Customer>) q.getResultList(); </li></ul>
    35. 35. createNamedQuery(String) <ul><li>Named queries are great </li></ul><ul><ul><li>Simplifies auditing of a system’s queries </li></ul></ul><ul><ul><li>Earlier validations </li></ul></ul><ul><ul><li>Deploy-time overrides (including SQL) </li></ul></ul><ul><li>Global scoping is bad </li></ul><ul><ul><li>Developers cannot not reuse query names </li></ul></ul><ul><ul><li>Impls must scan ALL entities for queries </li></ul></ul><ul><ul><li>Future versions cannot make local scoping the default </li></ul></ul>
    36. 36. createNamedQuery(String) <ul><li>@Entity </li></ul><ul><li>@NamedQuery(name= “ findAll ” , query= “ select p from Person p ” ) </li></ul><ul><li>public class Person { ... } </li></ul><ul><li>@Entity </li></ul><ul><li>@NamedQuery(name= “ findAll ” , query= “ select po from PurchaseOrder po ” ) </li></ul><ul><li>public class PurchaseOrder { ... } </li></ul><ul><li>Query q = em.createNamedQuery( “ findAll ” ); </li></ul>
    37. 37. Reasons for Object Persistence vs RDB <ul><li>Reasons to use OODB or ORM: </li></ul><ul><ul><li>Use of OO in design and programming (avoid impedance mismatch) </li></ul></ul><ul><ul><li>Domain Model Intense solution </li></ul></ul><ul><ul><li>Hierarchic data </li></ul></ul><ul><ul><li>Navigational access </li></ul></ul>
    38. 38. Reasons For ORM vs OODB <ul><li>Legacy RDB (Relational Database) </li></ul><ul><li>(RDB) vendor independence </li></ul><ul><li>Vendor stability(?) </li></ul><ul><li>Schema migration </li></ul><ul><li>Tools </li></ul>
    39. 39. References <ul><li>“ JPA: The Good, The Bad, and The Ugly”, Patrick Linskey, BEA </li></ul><ul><li>“ Object/Relational Mapping with Hibernate”, Gavin King, Hibernate </li></ul><ul><li>“ The Nuts and Bolts of Hibernate/JPA”, Jay Paulsen, ITS Administrative Information Systems </li></ul>

    ×