Overview of JPA (Java Persistence API) v2.0

93
Rochester JUG: 11-Oct-2011 Bryan Basham – Overview of JPA v2.0 Slide 1 © Copyright 2011, Software Alchemy Overview of JPA v2.0 (Java Persistence API) Bryan Basham Software Alchemy [email protected] http://www.linkedin.com/in/SoftwareAlchemist Containers & Deployment Query Language Entity Operations Entities In Practice Overview of JPA v2.0

description

JPA (Java Persistence API) is a JCP Standard for Object-Relational Mapping (ORM) persistence for the Java platform, both JavaSE and JavaEE. This talk will discuss and show examples from the latest version of the spec: JPA v2.0. Based upon influences from a variety of technologies that competed with the original JavaEE EJB specification for Entity beans, JPA promotes the use of light-weight POJO-based Entity objects and a simple EntityManger interface to control the CRUD operations to the backend RDBMS. Even with the rise of NoSQL data stores, there are still many applications that are well suited to a relational database solution and JPA is my favorite ORM tool for Java development. In the talk I will present: * Entities * Entity Operations * Query Language * Containers & Deployment * "In Practice" common problems, solutions and patterns of use

Transcript of Overview of JPA (Java Persistence API) v2.0

Page 1: Overview of JPA (Java Persistence API) v2.0

Rochester JUG: 11-Oct-2011

Bryan Basham – Overview of JPA v2.0 Slide 1

© Copyright 2011, Software Alchemy

Overview of JPA v2.0(Java Persistence API)

Bryan BashamSoftware Alchemy

[email protected]

http://www.linkedin.com/in/SoftwareAlchemist

Containers &Deployment

QueryLanguage

EntityOperations

Entities

In Practice

Overviewof JPA v2.0

Page 2: Overview of JPA (Java Persistence API) v2.0

Rochester JUG: 11-Oct-2011

Bryan Basham – Overview of JPA v2.0 Slide 2

© Copyright 2011, Software Alchemy

History

● Java v1.1 (1997) included JDBC● J2EE v1.2 (1999) introduced EJB Entity beans● Entity beans sucked, so others did it better

– iBATIS (2001)– Hibernate (2001)– JDO (JSR 12, final in 2002)

● JPA v1.0 (JSR 220) was released in 2006● JPA v2.0 (JSR 317) was released in 2009

Page 3: Overview of JPA (Java Persistence API) v2.0

Rochester JUG: 11-Oct-2011

Bryan Basham – Overview of JPA v2.0 Slide 3

© Copyright 2011, Software Alchemy

Who Needs a Standard?

● JPA provides a flexible standard● Multiple, competing implementations

– DataNucleus – EclipseLink – Hibernate – ObjectDB – OpenJPA

Page 4: Overview of JPA (Java Persistence API) v2.0

Rochester JUG: 11-Oct-2011

Bryan Basham – Overview of JPA v2.0 Slide 4

© Copyright 2011, Software Alchemy

Typical Architecture #1

The Java Virtual Machine

Java Lang / JRE JDK

JPA

EclipseLink OpenJPA

Your Standalone Application

Spring(optional)

Hibernate(plus optional libs)

Page 5: Overview of JPA (Java Persistence API) v2.0

Rochester JUG: 11-Oct-2011

Bryan Basham – Overview of JPA v2.0 Slide 5

© Copyright 2011, Software Alchemy

Typical Architecture #2

The Java Virtual Machine

Java Lang / JRE JDK

JPA

Your Enterprise Application

Spring(optional)

Hibernate(plus optional libs)

Java EE(servlets, JSP, JSF, EJB, JNDI, etc.)

Page 6: Overview of JPA (Java Persistence API) v2.0

Rochester JUG: 11-Oct-2011

Bryan Basham – Overview of JPA v2.0 Slide 6

© Copyright 2011, Software Alchemy

Entities

Containers &Deployment

QueryLanguage

EntityOperationsIn Practice

Overviewof JPA v2.0

RelationshipsKeys

Beans &Properties

Inheritance

DB MappingsEntities

Page 7: Overview of JPA (Java Persistence API) v2.0

Rochester JUG: 11-Oct-2011

Bryan Basham – Overview of JPA v2.0 Slide 7

© Copyright 2011, Software Alchemy

Entity Classes

● Any POJO, but should be a Java Bean● Class must not be final; nor methods or

persistence instance variables● May be Serializable and be passed across

remote calls, such as RMI● Entities may exist in a class hierarchy● Queries may be polymorphic

Page 8: Overview of JPA (Java Persistence API) v2.0

Rochester JUG: 11-Oct-2011

Bryan Basham – Overview of JPA v2.0 Slide 8

© Copyright 2011, Software Alchemy

Entity Classes: Example

import javax.persistence.Basic;import javax.persistence.Entity;

@Entity /** Not fully baked */public class Employee {

@Basic(optional=false) private String firstName; @Basic(optional=false) private String lastName; @Basic(optional=false) private Integer age;

public String getFirstName() { return firstName; } public void setFirstName(String name) { this.firstName = name; }

public String getLastName() { return lastName; } public void setLastName(String name) { this.lastName = name; }

public Integer getAge() { return age; } public void setAge(Integer age) { this.age = age; }

}

«entity»Employee

firstName : StringlastName : Stringage : Integer

Page 9: Overview of JPA (Java Persistence API) v2.0

Rochester JUG: 11-Oct-2011

Bryan Basham – Overview of JPA v2.0 Slide 9

© Copyright 2011, Software Alchemy

Access Types

● Access to DB fields can be on instance variables or properties

● You can specific the access type with an annotation:

@Entity@Access(AccessType.PROPERTY)public class Employee { /* entity code */ }

● If no access type is defined, then the default type (by usage) applies to the whole entity class hierarchy

Page 10: Overview of JPA (Java Persistence API) v2.0

Rochester JUG: 11-Oct-2011

Bryan Basham – Overview of JPA v2.0 Slide 10

© Copyright 2011, Software Alchemy

Entity Classes: Example #2

// assume all necessary imports from now on

@Entity@Access(AccessType.PROPERTY)public class Employee {

private String _firstName; private String _lastName; private Integer _age;

@Basic(optional=false) public String getFirstName() { return _firstName; } public void setFirstName(String name) { this._firstName = name; }

@Basic(optional=false) public String getLastName() { return _lastName; } public void setLastName(String name) { this._lastName = name; }

@Basic(optional=false) public Integer getAge() { return _age; } public void setAge(Integer age) { this._age = age; }

Page 11: Overview of JPA (Java Persistence API) v2.0

Rochester JUG: 11-Oct-2011

Bryan Basham – Overview of JPA v2.0 Slide 11

© Copyright 2011, Software Alchemy

Data Types

● A property data type can be:– any Java primitive– any Java primitive wrapper– Strings– Dates– Big integer and decimals– Byte arrays (for BLOBs)– Character arrays (for CLOBs)– Enum values

Page 12: Overview of JPA (Java Persistence API) v2.0

Rochester JUG: 11-Oct-2011

Bryan Basham – Overview of JPA v2.0 Slide 12

© Copyright 2011, Software Alchemy

Enum Types

@Entitypublic class Employee {

public enum Gender { MALE, FEMALE }

@Basic(optional = false) private Gender gender;

@Basic(optional=false) private String firstName;

@Basic(optional=false) private String lastName;

@Basic(optional=false) private Integer age;

«entity»Employee

gender : GenderfirstName : StringlastName : Stringage : Integer

«enumeratedType»Gender

+MALE+FEMALE

Enum ordinal

Page 13: Overview of JPA (Java Persistence API) v2.0

Rochester JUG: 11-Oct-2011

Bryan Basham – Overview of JPA v2.0 Slide 13

© Copyright 2011, Software Alchemy

Derived Properties

@Entitypublic class Employee {

@Basic(optional=false) private String firstName;

@Basic(optional=false) private String lastName;

@Basic(optional=false) private Date dateOfBirth;

@Transient private Integer age;

public Integer getAge() { if ( this.age == null ) { this.age = DateUtils.dateDiffYears(new Date(), this.dateOfBirth); } return age; }

«entity»Employee

firstName : StringlastName : StringdateOfBirth : Date#age : Integer

Page 14: Overview of JPA (Java Persistence API) v2.0

Rochester JUG: 11-Oct-2011

Bryan Basham – Overview of JPA v2.0 Slide 14

© Copyright 2011, Software Alchemy

Embeddable Properties

● Useful for representing small, non-entity classes

● Thus supports DDD Value Object concepts (well, almost)

● Also supports Composition without the need for cascading deletes (fields are embedded within the owning entity table)

● One Embeddable can embed other Embeddables

Page 15: Overview of JPA (Java Persistence API) v2.0

Rochester JUG: 11-Oct-2011

Bryan Basham – Overview of JPA v2.0 Slide 15

© Copyright 2011, Software Alchemy

Embeddable Properties (2)

@Embeddablepublic class PhoneNumber {

@Basic(optional=false) private String areaCode; // unfortunately, can't make these final @Basic(optional=false) private String localNumber; @Basic(optional=true) private String extension;

public PhoneNumber() { /* no-arg ctor for JPA */ } public PhoneNumber(String areaCode, String localNumber, String extension) { this.areaCode = areaCode; this.localNumber = localNumber; this.extension = extension; }

public String getAreaCode() { return areaCode; } public String getLocalNumber() { return localNumber; } public String getExtension() { return extension; }}

Page 16: Overview of JPA (Java Persistence API) v2.0

Rochester JUG: 11-Oct-2011

Bryan Basham – Overview of JPA v2.0 Slide 16

© Copyright 2011, Software Alchemy

Embeddable Properties (3)

«entity»Employee

firstName : StringlastName : StringdateOfBirth : Date#age : IntegerofficePhone : PhoneNumber

«valueObject»PhoneNumber

areaCode : StringlocalNumber : Stringextension : String

officePhone

1

@Entitypublic class Employee {

@Embedded private PhoneNumber officePhone;

Fields of the Embeddableare embedded directly intothe table of the owning Entity.

Page 17: Overview of JPA (Java Persistence API) v2.0

Rochester JUG: 11-Oct-2011

Bryan Basham – Overview of JPA v2.0 Slide 17

© Copyright 2011, Software Alchemy

Embeddable Properties (4)

@Entitypublic class Employee {

@Embedded @ElementCollection(fetch = FetchType.LAZY) private Map<String,PhoneNumber> phones = new HashMap<String,PhoneNumber>();

Due to the one-to-manythe embeddables are storedin a separate table.

«entity»Employee

firstName : StringlastName : StringdateOfBirth : Date#age : Integerphones : Map<String, PhoneNumber>

«valueObject»PhoneNumber

areaCode : StringlocalNumber : Stringextension : String

1type

Entity FK Map key

Page 18: Overview of JPA (Java Persistence API) v2.0

Rochester JUG: 11-Oct-2011

Bryan Basham – Overview of JPA v2.0 Slide 18

© Copyright 2011, Software Alchemy

Entity Keys

● Every entity must have a primary key● Key is specified with the @Id annotation● Only one key defined for a given entity class

hierarchy● Keys can be simple or composite● Simple key (or properties of a composite key)

must have a simple data type:– Strings, Java primitives (or wrappers), dates, or

big numbers

Page 19: Overview of JPA (Java Persistence API) v2.0

Rochester JUG: 11-Oct-2011

Bryan Basham – Overview of JPA v2.0 Slide 19

© Copyright 2011, Software Alchemy

Entity Keys: Example

@Entitypublic class Employee {

@Id @Basic(optional=false) // SSN must be unique (not a good choice) private String SSN;

@Basic(optional=false) private String firstName;

@Basic(optional=false) private String lastName;

@Basic(optional=false) private Date dateOfBirth;

@Transient private Integer age;

«entity»Employee

SSN : StringfirstName : StringlastName : StringdateOfBirth : Date#age : Integer

Page 20: Overview of JPA (Java Persistence API) v2.0

Rochester JUG: 11-Oct-2011

Bryan Basham – Overview of JPA v2.0 Slide 20

© Copyright 2011, Software Alchemy

Entity Keys: Example #2

@Entitypublic class Employee {

@Id @GeneratedValue // let the DBMS assign the key on insert private Long id;

@Basic(optional=false) private String firstName;

@Basic(optional=false) private String lastName;

@Basic(optional=false) private Date dateOfBirth;

@Transient private Integer age;

«entity»Employee

id : LongfirstName : StringlastName : StringdateOfBirth : Date#age : Integer

MySQL uses autoincrementfor key generation.

Page 21: Overview of JPA (Java Persistence API) v2.0

Rochester JUG: 11-Oct-2011

Bryan Basham – Overview of JPA v2.0 Slide 21

© Copyright 2011, Software Alchemy

Associations

● Entities can be associated to other Entities and Embeddable objects

● Collections (bags), sets, sorted sets, lists, and even maps

● One-to-one, one-to-many, many-to-one, and many-to-many

● Uni- and bi-directional relationships● Lazy and Eager fetching techniques

Page 22: Overview of JPA (Java Persistence API) v2.0

Rochester JUG: 11-Oct-2011

Bryan Basham – Overview of JPA v2.0 Slide 22

© Copyright 2011, Software Alchemy

One-to-One

@Entitypublic class User {

@Id @GeneratedValue private Long id; @Basic(optional=false) private String userName; @Basic(optional=false) private String password;

@Basic(optional=false) @OneToOne(fetch=FetchType.EAGER) private Employee employee;

employee

1«entity»User

id : LonguserName : Stringpassword : Stringemployee : Employee

1 «entity»Employee

id : LongfirstName : StringlastName : StringdateOfBirth : Date#age : Integer

Page 23: Overview of JPA (Java Persistence API) v2.0

Rochester JUG: 11-Oct-2011

Bryan Basham – Overview of JPA v2.0 Slide 23

© Copyright 2011, Software Alchemy

One-to-One (2)

private void createExampleUser() { Calendar cal = Calendar.getInstance(); try { em.getTransaction().begin();

Employee emp = new Employee(); emp.setGender(Gender.MALE); emp.setFirstName("Bryan"); emp.setLastName("Basham"); cal.set(1964, 7, 22); emp.setDateOfBirth(cal.getTime()); em.persist(emp); // NOTE: need to persist all entities User u1 = new User(); u1.setUserName("bbasham"); u1.setPassword("guess"); u1.setEmployee(emp); em.persist(u1);

em.getTransaction().commit(); } catch (Exception e) { e.printStackTrace(); em.getTransaction().rollback(); }}

Page 24: Overview of JPA (Java Persistence API) v2.0

Rochester JUG: 11-Oct-2011

Bryan Basham – Overview of JPA v2.0 Slide 24

© Copyright 2011, Software Alchemy

One-to-Many

@Entitypublic class Department {

@Id @GeneratedValue private Long id;

@Basic(optional = false) private String name;

@OneToMany(fetch = FetchType.LAZY) private Set<Employee> staff;

staff

0..*«entity»Department

id : Longname : Stringstaff : Set<Employee>

1 «entity»Employee

id : LongfirstName : StringlastName : StringdateOfBirth : Date#age : Integer

Page 25: Overview of JPA (Java Persistence API) v2.0

Rochester JUG: 11-Oct-2011

Bryan Basham – Overview of JPA v2.0 Slide 25

© Copyright 2011, Software Alchemy

Many-to-Many

team

0..*«entity»Project

id : Longname : Stringteam : Set<Employee>

0..* «entity»Employee

id : LongfirstName : StringlastName : StringdateOfBirth : Date#age : Integerprojects : Set<Project>

projects

Page 26: Overview of JPA (Java Persistence API) v2.0

Rochester JUG: 11-Oct-2011

Bryan Basham – Overview of JPA v2.0 Slide 26

© Copyright 2011, Software Alchemy

Many-to-Many (2)

@Entitypublic class Employee {

@Id @GeneratedValue private Long id;

// Skipping basic properties

@ManyToMany(fetch = FetchType.LAZY, mappedTo=”team”) private Set<Project> projects;

@Entitypublic class Project {

@Id @GeneratedValue private Long id;

@Basic(optional = false) private String name;

@ManyToMany(fetch = FetchType.LAZY) private Set<Employee> team;

The mappedTo valuespecifies that the Project entityis the “owner” of the relationship.

Page 27: Overview of JPA (Java Persistence API) v2.0

Rochester JUG: 11-Oct-2011

Bryan Basham – Overview of JPA v2.0 Slide 27

© Copyright 2011, Software Alchemy

Many-to-Many (3)

Project FK Employee FK

Page 28: Overview of JPA (Java Persistence API) v2.0

Rochester JUG: 11-Oct-2011

Bryan Basham – Overview of JPA v2.0 Slide 28

© Copyright 2011, Software Alchemy

Inheritance

● JPA supports flexible Entity inheritance● A Entity may be an abstract class● An Entity class can extend a non-Entity class● A non-Entity class can extend an Entity class● Queries can be written to any Entity classes● Three DB mapping strategies:

– SINGLE_TABLE (the default)– JOINED – TABLE_PER_CLASS (not required per spec)

Page 29: Overview of JPA (Java Persistence API) v2.0

Rochester JUG: 11-Oct-2011

Bryan Basham – Overview of JPA v2.0 Slide 29

© Copyright 2011, Software Alchemy

Inheritance Example

team11

team21

«entity»Team

game1

1

game2

1

«entity»IntermediateGame

game1 : AbstractGamegame2 : AbstractGame

«entity»StartingTeam

team1 : Teamteam2 : Team

«entity»AbstractGame

id : Longteam1Score : intteam2Score : int

getTeam1() : TeamgetTeam2() : TeamgetWinner() : Team

Page 30: Overview of JPA (Java Persistence API) v2.0

Rochester JUG: 11-Oct-2011

Bryan Basham – Overview of JPA v2.0 Slide 30

© Copyright 2011, Software Alchemy

Single Table Example

@Entity@Inheritance(strategy=InheritanceType.SINGLE_TABLE)@DiscriminatorColumn( name="game_type" )public abstract class AbstractGame { @Id @GeneratedValue private Long id; @Basic(optional=false) private Integer team1Score; @Basic(optional=false) private Integer team2Score;

@Entity@DiscriminatorValue("SG")public class StartingGame extends AbstractGame { @Basic(optional=false) private Team team1; @Basic(optional=false) private Team team2;

@Entity@DiscriminatorValue("IG")public class IntermediateGame extends AbstractGame { @Basic(optional=false) private AbstractGame game1; @Basic(optional=false) private AbstractGame game2;

Page 31: Overview of JPA (Java Persistence API) v2.0

Rochester JUG: 11-Oct-2011

Bryan Basham – Overview of JPA v2.0 Slide 31

© Copyright 2011, Software Alchemy

Single Table Example (2)AbstractGame IntermediateGame

discriminatorfield

StartingGame

Page 32: Overview of JPA (Java Persistence API) v2.0

Rochester JUG: 11-Oct-2011

Bryan Basham – Overview of JPA v2.0 Slide 32

© Copyright 2011, Software Alchemy

Joined Example

@Entity@Inheritance(strategy=InheritanceType.JOINED)public abstract class AbstractGame { @Id @GeneratedValue private Long id; @Basic(optional=false) private Integer team1Score; @Basic(optional=false) private Integer team2Score;

@Entitypublic class StartingGame extends AbstractGame { @Basic(optional=false) private Team team1; @Basic(optional=false) private Team team2;

@Entitypublic class IntermediateGame extends AbstractGame { @Basic(optional=false) private AbstractGame game1; @Basic(optional=false) private AbstractGame game2;

Page 33: Overview of JPA (Java Persistence API) v2.0

Rochester JUG: 11-Oct-2011

Bryan Basham – Overview of JPA v2.0 Slide 33

© Copyright 2011, Software Alchemy

Joined Example (2)IntermediateGame

StartingGame

AbstractGame

Page 34: Overview of JPA (Java Persistence API) v2.0

Rochester JUG: 11-Oct-2011

Bryan Basham – Overview of JPA v2.0 Slide 34

© Copyright 2011, Software Alchemy

Database Mappings

● JPA implementations like Hibernate can dynamically create a DB schema for RAD

● But if you have an existing schema, then you can use annotations to map:

– Entity classes to tables– Entity properties to fields– Join columns of relationships– ...and more

Page 35: Overview of JPA (Java Persistence API) v2.0

Rochester JUG: 11-Oct-2011

Bryan Basham – Overview of JPA v2.0 Slide 35

© Copyright 2011, Software Alchemy

Domain Model Example

«entity»Employee

firstName : StringlastName : StringdateOfBirth : Date#age : Integerphones : Map<>projects : Set<Project>user : Userdepartment : Department

«valueObject»PhoneNumber

areaCode : StringlocalNumber : Stringextension : String

1type

team0..*

«entity»Project

id : Longname : Stringteam : Set<Employee>

0..* projects

staff0..*

«entity»Department

id : Longname : Stringstaff : Set<Employee>

employee

1«entity»User

id : LonguserName : Stringpassword : Stringemployee : Employee

1

department1

Page 36: Overview of JPA (Java Persistence API) v2.0

Rochester JUG: 11-Oct-2011

Bryan Basham – Overview of JPA v2.0 Slide 36

© Copyright 2011, Software Alchemy

ER Diagram«table»USR

SID : BIGINT(20)NAME : VARCHAR(32)PW : VARCHAR(16)EMP_SID : NUMBER(20)

«table»DEPT

SID : BIGINT(20)NAME : VARCHAR(64)

«table»EMP

SID : BIGINT(20)FNAME : VARCHAR(100)LNAME : VARCHAR(100)DOB : DATETIMEGEN_CODE : VARCHAR(6)

«table»PRJ

SID : BIGINT(20)NAME : VARCHAR(64)

«table»PRJ_EMP

PRJ_SID : BIGINT(20)EMP_SID : BIGINT(20)

«table»EMP_PHONE

EMP_SID : BIGINT(20)TYPE : VARCHAR(7)AREA_CODE : CHAR(3)NUMBER : CHAR(4)EXT : CHAR(3)

Page 37: Overview of JPA (Java Persistence API) v2.0

Rochester JUG: 11-Oct-2011

Bryan Basham – Overview of JPA v2.0 Slide 37

© Copyright 2011, Software Alchemy

Basic DB Mappings

@Entity@Table(name="EMP")public class Employee {

@Id @GeneratedValue @Column(name="SID") private Long id;

@Basic(optional = false) @Column(name="GEN_CODE", length=6) @Enumerated(value=EnumType.STRING) private Gender gender;

@Basic(optional=false) @Column(name="FNAME", length=100) private String firstName;

@Basic(optional=false) @Column(name="LNAME", length=100) private String lastName;

Page 38: Overview of JPA (Java Persistence API) v2.0

Rochester JUG: 11-Oct-2011

Bryan Basham – Overview of JPA v2.0 Slide 38

© Copyright 2011, Software Alchemy

Relationship Mappings

@Entity@Table(name="USR")public class User {

@Id @GeneratedValue @Column(name="SID") private Long id

@Basic(optional = false) @Column(name="NAME", length=32, unique=true) private String userName;

@Basic(optional = false) @Column(name="PW", length=16) private String password;

@Basic(optional = false) @OneToOne(fetch = FetchType.EAGER, cascade={CascadeType.ALL}) @JoinColumn(name="EMP_SID") private Employee employee;

Page 39: Overview of JPA (Java Persistence API) v2.0

Rochester JUG: 11-Oct-2011

Bryan Basham – Overview of JPA v2.0 Slide 39

© Copyright 2011, Software Alchemy

Relationship Mappings (2)

@Entity@Table(name = "PRJ")public class Project {

@Id @GeneratedValue @Column(name = "SID") private Long id;

@Basic(optional = false) @Column(name = "NAME", length=64) private String name;

@ManyToMany(fetch = FetchType.EAGER) @JoinTable(name = "PRJ_EMP", joinColumns = { @JoinColumn(name = "PRJ_SID", referencedColumnName = "SID") }, inverseJoinColumns = { @JoinColumn(name = "EMP_SID", referencedColumnName = "SID") }) private Set<Employee> team = new HashSet<Employee>();

Page 40: Overview of JPA (Java Persistence API) v2.0

Rochester JUG: 11-Oct-2011

Bryan Basham – Overview of JPA v2.0 Slide 40

© Copyright 2011, Software Alchemy

Embeddable Mappings

@Entity@Table(name="EMP")public class Employee { @Embedded @ElementCollection(fetch = FetchType.LAZY) @CollectionTable(name="EMP_PHONE", joinColumns={ @JoinColumn(name="EMP_SID", referencedColumnName="SID") }) @MapKeyColumn(name="PHONE_TYPE") private Map<String, PhoneNumber> phones = new HashMap<String, PhoneNumber>();

@Embeddablepublic class PhoneNumber { @Column(name="AREA_CODE", length=3) private String areaCode; @Column(name="NUMBER", length=7) private String localNumber; @Column(name="AREA_CODE", length=3, nullable=true) private String areaCode;

Page 41: Overview of JPA (Java Persistence API) v2.0

Rochester JUG: 11-Oct-2011

Bryan Basham – Overview of JPA v2.0 Slide 41

© Copyright 2011, Software Alchemy

Containers &Deployment

QueryLanguage

In Practice

CRUD OpsEntityManager

Other operations

EntityOperations

RelationshipsKeys

Beans &Properties

Inheritance

DB MappingsEntities

Overviewof JPA v2.0

Entity Operations

Page 42: Overview of JPA (Java Persistence API) v2.0

Rochester JUG: 11-Oct-2011

Bryan Basham – Overview of JPA v2.0 Slide 42

© Copyright 2011, Software Alchemy

Entity Manager

«class»Persistence

{from javax.persistence}

createEntityManager- Factory(String puName) : EMF

META-INF/persistence.xml

....

..

.....

....

«interface»EntityManagerFactory{from javax.persistence}

createEntityManager() : EM

«interface»EntityManager

{from javax.persistence}

persist(entity:Object) : voidfind(eCls:Class<T>, key:Object) : Tmerge(entity:T) : Tremove(entity:Object)

Page 43: Overview of JPA (Java Persistence API) v2.0

Rochester JUG: 11-Oct-2011

Bryan Basham – Overview of JPA v2.0 Slide 43

© Copyright 2011, Software Alchemy

CRUD Operations

● Create:– Just create an Entity POJO with no id– Call em.persist(entity); JPA populates id

● Retrieve:– Employee emp = em.find(Employee.class, 47L);

● Update:– Create POJO with id; call em.merge(entity)

● Delete:– Create POJO with id; call em.remove(entity)

Page 44: Overview of JPA (Java Persistence API) v2.0

Rochester JUG: 11-Oct-2011

Bryan Basham – Overview of JPA v2.0 Slide 44

© Copyright 2011, Software Alchemy

Persisting Relationships

● By default, you must persist all parts by hand– Remember our example:

// Make and persist an employeeEmployee emp = new Employee(); // setters skippedem.persist(emp);// Make and persist a userUser user = new User(); // setters skippeduser.setEmployee(emp);em.persist(user);

● You can tell JPA to persist parts with many relationship annotations

Page 45: Overview of JPA (Java Persistence API) v2.0

Rochester JUG: 11-Oct-2011

Bryan Basham – Overview of JPA v2.0 Slide 45

© Copyright 2011, Software Alchemy

Cascading Operations@Entitypublic class User {

@Id @GeneratedValue private Long id; @Basic(optional=false) private String userName; @Basic(optional=false) private String password;

@Basic(optional=false) @OneToOne(fetch=FetchType.EAGER , cascade={CascadeType.ALL}) private Employee employee;

private void createExampleUser() { em.getTransaction().begin(); // Make an employee Employee emp = new Employee(); // setters skipped // Make a user User user = new User(); // setters skipped user.setEmployee(emp); // Persist the User and the Employee is automatically saved em.persist(user);

Page 46: Overview of JPA (Java Persistence API) v2.0

Rochester JUG: 11-Oct-2011

Bryan Basham – Overview of JPA v2.0 Slide 46

© Copyright 2011, Software Alchemy

Other EM Operations

● flush()

– Saves EM context state to DB● detach(entity)

– Detaches an Entity from EM context● refresh(entity)

– Refreshes the Entity state from the DB● getReference(id):T

– Retrieves a lazy Entity from the DB

Page 47: Overview of JPA (Java Persistence API) v2.0

Rochester JUG: 11-Oct-2011

Bryan Basham – Overview of JPA v2.0 Slide 47

© Copyright 2011, Software Alchemy

Containers &Deployment

In Practice

UPDATE &DELETE

SELECT

Joins

SELECT Clause

Expressions

QueryParameters

QueryLanguage

RelationshipsKeys

Beans &Properties

CRUD OpsEntityManager

Other operations

EntityOperations

Inheritance

DB MappingsEntities

Overviewof JPA v2.0

Query Language

Page 48: Overview of JPA (Java Persistence API) v2.0

Rochester JUG: 11-Oct-2011

Bryan Basham – Overview of JPA v2.0 Slide 48

© Copyright 2011, Software Alchemy

SELECT Statements

● Like SQL SELECT statements; except it selects a whole Entity object

● Examples:– SELECT e FROM Employee AS e – SELECT e FROM Employee AS e

JOIN e.projects p WHERE p.name = 'Cobia'

● Code:String statement = "SELECT e FROM Employee AS e";TypedQuery<Employee> query = em.createQuery(statement, Employee.class);List<Employee> list = query.getResultList();

Page 49: Overview of JPA (Java Persistence API) v2.0

Rochester JUG: 11-Oct-2011

Bryan Basham – Overview of JPA v2.0 Slide 49

© Copyright 2011, Software Alchemy

Query Parameters

● Supports JDBC-like indexed parameters:private List<Employee> queryTeam(Project project) { String statement = "SELECT e FROM Employee AS e JOIN e.projects p WHERE p.name=?"; TypedQuery<Employee> query = em.createQuery(statement, Employee.class); query.setParameter(1, project.getName()); return query.getResultList();}

● Also supports named parameters:private List<Employee> queryTeam(Project project) { String statement = "SELECT e FROM Employee AS e JOIN e.projects p WHERE p.name=:PRJ"; TypedQuery<Employee> query = em.createQuery(statement, Employee.class); query.setParameter("PRJ", project.getName()); return query.getResultList();}

Page 50: Overview of JPA (Java Persistence API) v2.0

Rochester JUG: 11-Oct-2011

Bryan Basham – Overview of JPA v2.0 Slide 50

© Copyright 2011, Software Alchemy

Conditional Expressions

● Literals● Functions● Basic Operators● Collection Operators● Path expressions

Page 51: Overview of JPA (Java Persistence API) v2.0

Rochester JUG: 11-Oct-2011

Bryan Basham – Overview of JPA v2.0 Slide 51

© Copyright 2011, Software Alchemy

Literals

● Strings: 'string' and 'string''s'● Boolean: TRUE and FALSE● Numbers: both Java and SQL literals● Dates: {d '2011-10-11'}

– This syntax is handled by the JDBC provider– The JPA provider is not required to mediate

● Enums: org.basham.TestJPA.entities.Gender.MALE – Probably best to just pass in as a parameter

Page 52: Overview of JPA (Java Persistence API) v2.0

Rochester JUG: 11-Oct-2011

Bryan Basham – Overview of JPA v2.0 Slide 52

© Copyright 2011, Software Alchemy

Functions

● Strings: CONCAT, SUBSTRING, TRIM, UPPER, LOWER, LENGTH, LOCATE

● Numeric: ABS, SQRT, MOD, SIZE(collection), INDEX(item in a List)

● Temporal: CURRENT_DATE, CURRENT_TIME, and CURRENT_TIMESTAMP

● CASE statement● Entity Type: TYPE(game) = StartingGame

Page 53: Overview of JPA (Java Persistence API) v2.0

Rochester JUG: 11-Oct-2011

Bryan Basham – Overview of JPA v2.0 Slide 53

© Copyright 2011, Software Alchemy

Basic Operators

● Comparison: <, <=, =, <>, >, >=● Arithmetic: +, -, *, /● Logical: NOT, AND, and OR● Between: x [NOT] BETWEEN y AND z● String matching: x [NOT] LIKE 'B%' ● Null check: x IS [NOT] NULL

Page 54: Overview of JPA (Java Persistence API) v2.0

Rochester JUG: 11-Oct-2011

Bryan Basham – Overview of JPA v2.0 Slide 54

© Copyright 2011, Software Alchemy

Collection Operators

● Fixed membership:– a [NOT] IN (x, y, z, ...)

● Empty:– collection IS [NOT] EMPTY

● Flexible membership:– entity [NOT] MEMBER [OF] collection

private List<Employee> queryTeam(Project project) { String st = "SELECT e FROM Employee e WHERE :PRJ MEMBER OF e.projects"; TypedQuery<Employee> query = em.createQuery(st, Employee.class); query.setParameter("PRJ", project); return query.getResultList();}

Page 55: Overview of JPA (Java Persistence API) v2.0

Rochester JUG: 11-Oct-2011

Bryan Basham – Overview of JPA v2.0 Slide 55

© Copyright 2011, Software Alchemy

Path Expressions

● Allows simple object navigation– OneToOne and ManyToOne relationships– Single Embedded properties (no collections)

● Examples:– How many Employees with short passwords?

SELECT count(e) FROM Employee e WHERE LENGTH(e.user.password) <= 4

– How many Employees with office phones in Rochester?

SELECT count(e) FROM Employee e WHERE e.officePhone.areaCode = '585'

Page 56: Overview of JPA (Java Persistence API) v2.0

Rochester JUG: 11-Oct-2011

Bryan Basham – Overview of JPA v2.0 Slide 56

© Copyright 2011, Software Alchemy

Joins

● Like SQL joins; natural for relationship traversal● Support for outer join● Support for so-called “FETCH JOIN” which

allows the query to specify a Lazy relationship to be pre-fetched.

Page 57: Overview of JPA (Java Persistence API) v2.0

Rochester JUG: 11-Oct-2011

Bryan Basham – Overview of JPA v2.0 Slide 57

© Copyright 2011, Software Alchemy

Join Examples

● Get Employees for a specific project and gender:

SELECT e FROM Employee AS e JOIN e.projects p WHERE p.name=:N AND e.gender=:SEX

● Get Projects with team members from a specific Department:

SELECT p FROM Project p JOIN p.team emp JOIN emp.department dept WHERE dept.name=:DEPT

Page 58: Overview of JPA (Java Persistence API) v2.0

Rochester JUG: 11-Oct-2011

Bryan Basham – Overview of JPA v2.0 Slide 58

© Copyright 2011, Software Alchemy

SELECT Clause

● Select Entity objects (most of what we've seen)– The result is an Entity object

● Select specific attributes (like SQL)– The result is an Object[] result

● Select aggregations (like SQL)– May use a GROUP BY clause

● May construct new Entities from a query● May use DISTINCT; like in SQL

Page 59: Overview of JPA (Java Persistence API) v2.0

Rochester JUG: 11-Oct-2011

Bryan Basham – Overview of JPA v2.0 Slide 59

© Copyright 2011, Software Alchemy

Aggregation Example

● Department stats: # of Emps and youngest age private void queryEmployeeStatsByDept(Department dept) { String statement = "SELECT COUNT(e), MAX(e.dateOfBirth) FROM Employee e JOIN e.department dept WHERE dept.name=:DEPT"; Query query = em.createQuery(statement); query.setParameter("DEPT", dept.getName()); Object[] tuple = (Object[]) query.getSingleResult(); Long numOfEmps = (Long) tuple[0]; Date minDOB = (Date) tuple[1]; System.out.println(String.format("There %d employees in the %s department with the youngest age of %d years.", numOfEmps, dept.getName(), DateUtils.dateDiffYears(new Date(), minDOB))); }

There 5 employees in the IT department with the youngest age of 20 years.

Page 60: Overview of JPA (Java Persistence API) v2.0

Rochester JUG: 11-Oct-2011

Bryan Basham – Overview of JPA v2.0 Slide 60

© Copyright 2011, Software Alchemy

GROUP BY Example

● List # of Emps by Department and Genderprivate void queryDepartmentStats() { String statement = "SELECT dept.name, emp.gender, COUNT(emp) FROM Employee emp JOIN emp.department dept GROUP BY dept.name, emp.gender"; Query query = em.createQuery(statement); List<Object[]> list = (List<Object[]>) query.getResultList(); System.out.println("Department stats:"); for ( Object[] tuple : list ) { String deptName = (String) tuple[0]; Gender gender = (Gender) tuple[1]; Long numOfEmps = (Long) tuple[2]; System.out.println("\t" + deptName + " & " + gender.name() + " : " + numOfEmps + " employees"); }}

Department stats: Exec & FEMALE : 1 employees Exec & MALE : 5 employees HR & FEMALE : 1 employees HR & MALE : 6 employees ... and so on ...

Page 61: Overview of JPA (Java Persistence API) v2.0

Rochester JUG: 11-Oct-2011

Bryan Basham – Overview of JPA v2.0 Slide 61

© Copyright 2011, Software Alchemy

UPDATE and DELETE

● JPA also allows bulk updates and deletes● Syntax:

– UPDATE Entity AS e SET e.prop1=val1, e.prop2=val2, ... WHERE e.property = ?

– DELETE FROM Entity AS e WHERE e.property = ?

Page 62: Overview of JPA (Java Persistence API) v2.0

Rochester JUG: 11-Oct-2011

Bryan Basham – Overview of JPA v2.0 Slide 62

© Copyright 2011, Software Alchemy

UPDATE Example

private void resetPasswordsByDept(Department dept, String newPW) { try { em.getTransaction().begin();

String statement = "UPDATE User u SET u.password=? WHERE u.employee.id IN (SELECT e.id FROM Employee e WHERE e.department=?)"; Query query = em.createQuery(statement); query.setParameter(1, newPW); query.setParameter(2, dept); int howMany = query.executeUpdate(); System.out.println(String.format("%d user's passwords reset for %s", howMany, dept));

em.getTransaction().commit(); } catch (Exception e) { e.printStackTrace(); em.getTransaction().rollback(); } }

Page 63: Overview of JPA (Java Persistence API) v2.0

Rochester JUG: 11-Oct-2011

Bryan Basham – Overview of JPA v2.0 Slide 63

© Copyright 2011, Software Alchemy

In Practice

Packaging PersistenceUnit

Containers &Deployment

RelationshipsKeys

Beans &Properties

CRUD OpsEntityManager

Other operations

EntityOperations

Inheritance

DB MappingsEntities

UPDATE &DELETE

SELECT

Joins

SELECT Clause

Expressions

QueryParameters

QueryLanguage

Overviewof JPA v2.0

Containers & Deployment

Page 64: Overview of JPA (Java Persistence API) v2.0

Rochester JUG: 11-Oct-2011

Bryan Basham – Overview of JPA v2.0 Slide 64

© Copyright 2011, Software Alchemy

Persistence Unit

● JPA's configuration– Configuration of the persistence provider, such

as Hibernate– Set of entity classes; and what to exclude– Mapping configuration; if not provided by Entity

class annotations● Lives in the persistence.xml file

– Typically in the META-INF directory of a JAR– Or in the WEB-INF/classes directory of a WAR

Page 65: Overview of JPA (Java Persistence API) v2.0

Rochester JUG: 11-Oct-2011

Bryan Basham – Overview of JPA v2.0 Slide 65

© Copyright 2011, Software Alchemy

Persistence Unit (2)

<?xml version="1.0" encoding="UTF-8"?><persistence xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd" version="2.0">

<persistence-unit name="unit1" transaction-type="RESOURCE_LOCAL"> <!-- details --> </persistence-unit>

<persistence-unit name="unit2" transaction-type="RESOURCE_LOCAL"> <!-- details --> </persistence-unit> </persistence>

// code...EntityManagerFactory emf = Persistence.createEntityManagerFactory("unit1");EntityManager em = emf.createEntityManager();em.persist(entity);

Page 66: Overview of JPA (Java Persistence API) v2.0

Rochester JUG: 11-Oct-2011

Bryan Basham – Overview of JPA v2.0 Slide 66

© Copyright 2011, Software Alchemy

Persistence Unit (3)

<persistence ...>

<persistence-unit name="unit1" transaction-type="RESOURCE_LOCAL"> <provider>org.hibernate.ejb.HibernatePersistence</provider> <class>org.basham.TestJPA.mappings.Employee</class> <class>org.basham.TestJPA.mappings.User</class> <class>org.basham.TestJPA.mappings.Department</class> <class>org.basham.TestJPA.mappings.Project</class> <exclude-unlisted-classes /> <properties> <property name="hibernate.hbm2ddl.auto" value="create-drop" /> <property name="hibernate.show_sql" value="true" /> <property name="hibernate.cache.provider_class" value="org.hibernate.cache.HashtableCacheProvider" /> <property name="hibernate.dialect" value="org.hibernate.dialect.MySQLDialect" /> <property name="hibernate.connection.url" value="jdbc:mysql://localhost:8889/TestJPA_mappings" /> <property name="hibernate.connection.driver_class" value="com.mysql.jdbc.Driver" /> <property name="hibernate.connection.password" value="root" /> <property name="hibernate.connection.username" value="root" /> </properties> </persistence-unit> </persistence>

PersistenceProvider

configuration

EntityClasses

Page 67: Overview of JPA (Java Persistence API) v2.0

Rochester JUG: 11-Oct-2011

Bryan Basham – Overview of JPA v2.0 Slide 67

© Copyright 2011, Software Alchemy

Packaging a Standalone App

TestJPA.jar

mysql-connector-java-5.1.5.jar

hibernate-entitymanager-3.6.7-Final.jar

hibernate-jpa-2.0-api.jar

jta-1.1.jar

JSR-305.jar

Several other JARs

META-INF/persistence.xml

....

..

.....

....

Page 68: Overview of JPA (Java Persistence API) v2.0

Rochester JUG: 11-Oct-2011

Bryan Basham – Overview of JPA v2.0 Slide 68

© Copyright 2011, Software Alchemy

Building a Standalone w/ Maven

● If you just build a standalone JAR for your app– You must include all of the external JARs by

hand in the classpath during execution– Plus all of their dependencies (this gets complex)

● Or you can use Maven– To manage the transitive dependencies– And build a single executable JAR

Page 69: Overview of JPA (Java Persistence API) v2.0

Rochester JUG: 11-Oct-2011

Bryan Basham – Overview of JPA v2.0 Slide 69

© Copyright 2011, Software Alchemy

Standalone App POM

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>org.basham</groupId> <artifactId>TestJPA</artifactId> <version>0.0.1-SNAPSHOT</version> <packaging>jar</packaging>

<repositories> <repository> <id>repository.jboss.org</id> <name>Public JBoss Repository Group</name> <url>https://repository.jboss.org/nexus/content/groups/public-jboss/</url> <layout>default</layout> </repository> </repositories>

<!-- Build configuration and plugins -->

<!-- Build dependencies -->

</project>

Page 70: Overview of JPA (Java Persistence API) v2.0

Rochester JUG: 11-Oct-2011

Bryan Basham – Overview of JPA v2.0 Slide 70

© Copyright 2011, Software Alchemy

Standalone App POM (2)

<project ...>

<!-- Build configuration and plugins --> <build> <plugins> <plugin> <artifactId>maven-assembly-plugin</artifactId> <configuration> <archive> <manifest> <mainClass>org.basham.TestJPA.app.Main</mainClass> </manifest> </archive> <descriptorRefs> <descriptorRef>jar-with-dependencies</descriptorRef> </descriptorRefs> </configuration> </plugin> <!-- a few other typical Maven plugins --> </plugins> </build>

</project>

Page 71: Overview of JPA (Java Persistence API) v2.0

Rochester JUG: 11-Oct-2011

Bryan Basham – Overview of JPA v2.0 Slide 71

© Copyright 2011, Software Alchemy

Standalone App POM (3)

<project ...>

<!-- Build dependencies --> <dependencies> <dependency> <groupId>org.hibernate</groupId> <artifactId>hibernate-entitymanager</artifactId> <version>3.6.7.Final</version> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>5.1.12</version> <scope>runtime</scope> </dependency> <!-- a few other dependencies --> </dependencies>

</project>

Page 72: Overview of JPA (Java Persistence API) v2.0

Rochester JUG: 11-Oct-2011

Bryan Basham – Overview of JPA v2.0 Slide 72

© Copyright 2011, Software Alchemy

Packing a Web App

MyWebApp.war

mysql-connector-java-5.1.5.jar

hibernate-entitymanager-3.6.7-Final.jar

WEB-INF/lib

hibernate-jpa-2.0-api.jar

jta-1.1.jar

JSR-305.jar

Several other JARs

persistence.xml

....

..

.....

....

META-INF/

Page 73: Overview of JPA (Java Persistence API) v2.0

Rochester JUG: 11-Oct-2011

Bryan Basham – Overview of JPA v2.0 Slide 73

© Copyright 2011, Software Alchemy

Building a Web App

● Packing in a webapp is easier because all of the external JARs are placed in WEB-INF/lib

● Again, using Maven makes this really easy

Page 74: Overview of JPA (Java Persistence API) v2.0

Rochester JUG: 11-Oct-2011

Bryan Basham – Overview of JPA v2.0 Slide 74

© Copyright 2011, Software Alchemy

Partialloading

Paging &Ordering

Open ViewPattern

Locking

Caching

In Practice

RelationshipsKeys

Beans &Properties

CRUD OpsEntityManager

Other operations

EntityOperations

Paging &Ordering

Inheritance

DB MappingsEntities

UPDATE &DELETE

SELECT

Joins

SELECT Clause

Expressions

QueryParameters

QueryLanguage

Packaging PersistenceUnit

Containers &Deployment

Overviewof JPA v2.0

In Practice

Page 75: Overview of JPA (Java Persistence API) v2.0

Rochester JUG: 11-Oct-2011

Bryan Basham – Overview of JPA v2.0 Slide 75

© Copyright 2011, Software Alchemy

Paging and Ordering

● The following example demonstrates the use of paging, searching, and ordering in a real app

● This webapp, UserMgr, uses the following stack:

– GWT and GXT (ExtJS widgets in GWT)– Spring– JPA and Spring DAO utilities– MySQL

Page 76: Overview of JPA (Java Persistence API) v2.0

Rochester JUG: 11-Oct-2011

Bryan Basham – Overview of JPA v2.0 Slide 76

© Copyright 2011, Software Alchemy

UserMgr: Users Table

Table filtered byUserType and Last Name

Ordered bySelected Column

Page 77: Overview of JPA (Java Persistence API) v2.0

Rochester JUG: 11-Oct-2011

Bryan Basham – Overview of JPA v2.0 Slide 77

© Copyright 2011, Software Alchemy

UserMgr: Users Table (2)

Table supports Paging

Page 78: Overview of JPA (Java Persistence API) v2.0

Rochester JUG: 11-Oct-2011

Bryan Basham – Overview of JPA v2.0 Slide 78

© Copyright 2011, Software Alchemy

UserMgr: User Query Stack

MySQL«DAO»

UserDao

«helper»JpaDaoSupport

{from org.spgfrm.orm.jpa.support}

«GWT»UserGrid

«RPC»UserRpc

«service»UserSvc

«valueObject»QueryRequest

start : intpageSize : intsortField : “String”sortDir : {ASC, DESC}

«valueObject»PagedQueryResult

totalCount : intitems : List<T>

T=UserThe UserGrid component on thebrowser sends the request for anew page of Users via the GWTRPC async service which is notshown here.

Server-side code

«create»«create»

Page 79: Overview of JPA (Java Persistence API) v2.0

Rochester JUG: 11-Oct-2011

Bryan Basham – Overview of JPA v2.0 Slide 79

© Copyright 2011, Software Alchemy

UserMgr: UserDaoImpl

public PagedQueryResult<User> retrieveUsers(final UserType userType, final QueryRequest requestInfo) { // Count the number of Users in this user type int totalCount = getJdbcTemplate().queryForInt( "SELECT count(*) FROM user WHERE user_type_id = ?", new Object[] { userType.getId() });

// Create the dynamic query (set the ORDER BY field) String sortField = requestInfo.getSortField(); SortDir sortDir = requestInfo.getSortDirection(); final String queryString = String.format( "SELECT u FROM User u" + " WHERE u.userType = ? and u.deleted = false " + " ORDER BY u.%s %s", // eg) " ORDER BY u.lastName ASC" sortField, sortDir.name());

// Perform the query // SEE NEXT SLIDE

return new PagedQueryResult<User>(totalCount, users); }

Order-bycriteria

Pagingresults

Page 80: Overview of JPA (Java Persistence API) v2.0

Rochester JUG: 11-Oct-2011

Bryan Basham – Overview of JPA v2.0 Slide 80

© Copyright 2011, Software Alchemy

UserMgr: UserDaoImpl (2)

public PagedQueryResult<User> retrieveUsers(final UserType userType, final QueryRequest requestInfo) { final String queryString = // SEE PREVIOUS SLIDE

// Perform the query List<User> users = (List<User>) getJpaTemplate().executeFind( new JpaCallback() { public Object doInJpa(EntityManager em) throws PersistenceException { Query query = em.createQuery(queryString); query.setParameter(1, userType); query.setMaxResults(requestInfo.getPageSize()); query.setFirstResult(requestInfo.getStart()); return query.getResultList(); } });

return new PagedQueryResult<User>(totalCount, users); }

Pagingcriteria

Page 81: Overview of JPA (Java Persistence API) v2.0

Rochester JUG: 11-Oct-2011

Bryan Basham – Overview of JPA v2.0 Slide 81

© Copyright 2011, Software Alchemy

Partial Loading

● Associations can have a FetchType of either:– LAZY : Fetch when requested (aka “lazy loaded”)

● One-to-Many● Many-to-Many

– Or EAGER : Fetch when Entity is retrieved● One-to-One● Many-to-One

● Properties can also be lazy loaded– Default is eager

Page 82: Overview of JPA (Java Persistence API) v2.0

Rochester JUG: 11-Oct-2011

Bryan Basham – Overview of JPA v2.0 Slide 82

© Copyright 2011, Software Alchemy

Partial Loading Poor Example

@Entity@Table(name="USR_TYP")public class UserType {

@Id @GeneratedValue @Column(name="SID") private Long id;

@Column(name="NAME", length=32, unique=true) private String name;

@OneToMany(fetch = FetchType.EAGER) private Set<User> users;

«entity»UserType

users «entity»User

1..*

type

1

What's wrong withthis relationship?

It depends...

Page 83: Overview of JPA (Java Persistence API) v2.0

Rochester JUG: 11-Oct-2011

Bryan Basham – Overview of JPA v2.0 Slide 83

© Copyright 2011, Software Alchemy

Partial Loading Solution

● In the situation where there could be thousands of Users per UserType:

– Remove the bi-directional association– Provide a Service tier method to query the Users

by type, possibly with paging and filtering

«entity»UserType

«entity»User

type

1

«service»UserTypeService

getUsers(Long typeId) : Set<User>// better yet use// paging & filtering

Page 84: Overview of JPA (Java Persistence API) v2.0

Rochester JUG: 11-Oct-2011

Bryan Basham – Overview of JPA v2.0 Slide 84

© Copyright 2011, Software Alchemy

Partial Loading Example

@Entity@Table(name="USR")public class User {

@Id @GeneratedValue @Column(name="SID") private Long id;

@Basic(optional = false) @Column(name="NAME", length=32, unique=true) private String userName;

@Basic(optional = false , fetch = FetchType.LAZY) @Column(name="PW", length=16) private String password;

@Basic(optional = false) @OneToOne(fetch = FetchType.LAZY) @JoinColumn(name="EMP_SID") private Employee employee;

Don't want to exposethe user's passwordto the GUI.

Also, the GUI rarelyneeds access to theEmployee record.

Page 85: Overview of JPA (Java Persistence API) v2.0

Rochester JUG: 11-Oct-2011

Bryan Basham – Overview of JPA v2.0 Slide 85

© Copyright 2011, Software Alchemy

«DAO»UserDao

«GWT»UserGrid

«RPC»UserRpc

«service»UserSvc

Typical transaction boundary

«entity»User

«create»

The User object is “managed”within a transactional boundary.Outside that boundary the entitybecomes “detached”.

«entity»User

u.getEmployee().getAge()

But outside of the txn boundaryaccess to the associatedEmployee object fails:LazyInitializationException

Partial Loading Example (2)

Page 86: Overview of JPA (Java Persistence API) v2.0

Rochester JUG: 11-Oct-2011

Bryan Basham – Overview of JPA v2.0 Slide 86

© Copyright 2011, Software Alchemy

Open Session in View Pattern

«DAO»UserDao

«GWT»UserGrid

«RPC»UserRpc

«service»UserSvc

Transaction boundary

«entity»User

u.getEmployee().getAge()

«filter»Open

EntityManagerInViewFilter

● One solution is to move the transaction boundary up the stack (say in Servlet filter):

Page 87: Overview of JPA (Java Persistence API) v2.0

Rochester JUG: 11-Oct-2011

Bryan Basham – Overview of JPA v2.0 Slide 87

© Copyright 2011, Software Alchemy

Optimistic Locking

● Assumed, but code support must be injected● The @Version annotation is used to flag an

Entity attribute as the “version attribute”– @Version long version – @Version Date versionStamp

● An OptimisticLockException is thrown when one session attempts to update the entity after another session has already done so

Page 88: Overview of JPA (Java Persistence API) v2.0

Rochester JUG: 11-Oct-2011

Bryan Basham – Overview of JPA v2.0 Slide 88

© Copyright 2011, Software Alchemy

Pessimistic Locking

● Can lock an individual entity:User user = em.find(User.class, 47L);em.lock(user, LockModeType.PESSIMISTIC_WRITE);// OR simply:User user = em.find(User.class, 47L, LockModeType.PESSIMISTIC_WRITE);

● Can lock all entities returned by a query:String statement = // some limited queryTypedQuery<User> query = em.createQuery(statement, User.class);query.setLockMode(LockModeType.PESSIMISTIC_READ);List<User> users = query.getResultList();

Page 89: Overview of JPA (Java Persistence API) v2.0

Rochester JUG: 11-Oct-2011

Bryan Basham – Overview of JPA v2.0 Slide 89

© Copyright 2011, Software Alchemy

Caching

● The JPA spec supports the use of second-level caching by the persistence provider.

● The developer can mark Entity classes to be cached by the @Cacheable annotation.

● Similarly the developer can mark an Entity class to never be cached using: @Cacheable(false)

Page 90: Overview of JPA (Java Persistence API) v2.0

Rochester JUG: 11-Oct-2011

Bryan Basham – Overview of JPA v2.0 Slide 90

© Copyright 2011, Software Alchemy

Caching Example

@Entity@Cacheable(true)public class Category {

@Id @GeneratedValue private Long id;

private String title;

@ManyToOne private Category parent;

@Transient private Set<Category> children = new HashSet<Category>();

children0..*

parent

0..1«entity»Category

The Category entity representsa reflexive hierarchy that rarelychanges; thus is a good candidatefor caching.

Page 91: Overview of JPA (Java Persistence API) v2.0

Rochester JUG: 11-Oct-2011

Bryan Basham – Overview of JPA v2.0 Slide 91

© Copyright 2011, Software Alchemy

Overviewof JPA v2.0

RelationshipsKeys

Beans &Properties

CRUD OpsEntityManager

Other operations

EntityOperations

Partialloading

Paging &Ordering

Open ViewPattern

Locking

Caching

In Practice

Inheritance

DB MappingsEntities

UPDATE &DELETE

SELECT

Joins

SELECT Clause

Expressions

QueryParameters

QueryLanguage

Packaging PersistenceUnit

Containers &Deployment

Q & A

Page 92: Overview of JPA (Java Persistence API) v2.0

Rochester JUG: 11-Oct-2011

Bryan Basham – Overview of JPA v2.0 Slide 92

© Copyright 2011, Software Alchemy

Ten Great Topics Not Covered1) Composite keys; great for mapping to an existing DB schema

2) Primary key generation; eg) hashes or UUID

3) Native SQL queries

4) GROUP BY and HAVING clauses

5) More nuances of Entity relationships

6) More nuances to DB mappings

7) Entity lifecycle events and listeners (could be used for data manipulation or auditing)

8) Bean validation

9) Programmatic query APIs

10) Metamodel APIs

Page 93: Overview of JPA (Java Persistence API) v2.0

Rochester JUG: 11-Oct-2011

Bryan Basham – Overview of JPA v2.0 Slide 93

© Copyright 2011, Software Alchemy

Resources

● JPA v2.0– JSR 317 (click here)– Javadocs (click here)– Tutorials (click here)

● JPA Documentation– Wikipedia (click here)– Wikibooks (click here)