SlideShare ist ein Scribd-Unternehmen logo
1 von 269
Java Persistence API
Ilio Catallo - info@iliocatallo.it
Outline
• Object vs. rela/onal model
• En//es and EntityManager
• Integra/ng JPA into Spring
• Mapping rela/onships
• Querying the data source
• References
Object vs. rela.onal model
Object vs. rela.onal model
The end-point of every Web applica5on is the DBMS
Object vs. rela.onal model
In many cases, the DBMS has been around for much longer than
the Web applica;on
Object vs. rela.onal model
It is up to the object model of the Web app to find ways to work
with the database schema
Object vs. rela.onal model
The technique of bridging the gap between the object model and
the rela7onal model is known as object-rela+onal mapping (ORM)
Object vs. rela.onal model
Object-rela+onal mapping techniques try to map the concepts
from one model onto another
Impedance mismatch
┌───────────────────────────────┬──────────────────────────────┐
│////////// OOP Model //////////│////// Relational model /////│
├───────────────────────────────┼──────────────────────────────┤
│ Classes, objects │ Tables, rows │
├───────────────────────────────┼──────────────────────────────┤
│ Attributes, properties │ Columns │
├───────────────────────────────┼──────────────────────────────┤
│ Identity │ Primary key │
├───────────────────────────────┼──────────────────────────────┤
│ References to other entities │ Foreign key │
├───────────────────────────────┼──────────────────────────────┤
│ Inheritance, polymorphism │ Not supported │
├───────────────────────────────┼──────────────────────────────┤
│ Methods │ Stored procedures, triggers │
├───────────────────────────────┼──────────────────────────────┤
│ Code is portable │ Code is vendor-depending │
└───────────────────────────────┴──────────────────────────────┘
The challenge of mapping one model to the other lies in the concepts in
each for which there is no logical equivalent in the other
Impedance mismatch
As a result, moving data back and forth between a DBMS and the
object model is a lot harder than it needs to be
Impedance mismatch
Java developers find themselves spending effort in wri5ng lots of
code to convert rows and columns into objects
Impedance mismatch
The problem with JDBC
JDBC has been the first major support for database persistence
The problem with JDBC
JDBC offers an abstrac'on of the proprietary client programming
interfaces provided by database vendors
The problem with JDBC
Although JDBC is portable, the SQL language is not
The problem with JDBC
It is rare to write SQL of any complexity that runs unchanged on
two major database pla:orms
Java Persistence API
The Java Persistence API (JPA) bridges the gap between object-
oriented domain models and rela:onal database systems
Java Persistence API
JPA 2.1 was developed by the JSR-338 so:ware expert group
Java Persistence API
Despite its ini)al associa)on with EJBs, JPA is a JSE API, as
reflected by its belonging to the java.persistence package
Java Persistence API
JPA provides an ease-of-use abstrac5on on top of JDBC
┌──────────────────┐ ┌──────────────────┐
│ Java │ │ Vendor- │
│ Persistence API │ │ specific API │
└──────────────────┘ └──────────────────┘
┌───────────────────────────────────────┐
│ │ The persistence provider
│ Persistence provider │ is in charge of the ORM
│ │
└───────────────────────────────────────┘
┌───────────────────────────────────────┐
│ │ JDBC provides methods
│ JDBC │ for querying and updating
│ │ data in the database
└───────────────────────────────────────┘
┌───────────────────────────────────────┐
│ │
│ DBMS │
│ │
└───────────────────────────────────────┘
Java Persistence API
The code can therefore be isolated from vendor-specific
peculiari1es and rela1on model peculiari1es
┌──────────────────┐ ┌──────────────────┐
│ Java │ │ Vendor- │
│ Persistence API │ │ specific API │
└──────────────────┘ └──────────────────┘
┌───────────────────────────────────────┐
│ │ The persistence provider
│ Persistence provider │ is in charge of the ORM
│ │
└───────────────────────────────────────┘
┌───────────────────────────────────────┐
│ │ JDBC provides methods
│ JDBC │ for querying and updating
│ │ data in the database
└───────────────────────────────────────┘
┌───────────────────────────────────────┐
│ │
│ DBMS │
│ │
└───────────────────────────────────────┘
JPA main features
• POJO persistence
• Non-intrusiveness
• Object queries
POJO persistence
JPA provides a Plain Old Java Object (POJO) persistence model
public class Employee {
private int id;
private String name;
private long salary;
public Employee() {...}
// other methods (e.g., getters and setters)
}
POJO persistence
There is nothing special about the objects being persisted
public class Employee {
private int id;
private String name;
private long salary;
public Employee() {...}
// other methods (e.g., getters and setters)
}
POJO persistence
Any exis)ng non-final class with a default constructor can be
made persistable
public class Employee {
private int id;
private String name;
private long salary;
public Employee() {...}
// other methods (e.g., getters and setters)
}
Non-intrusiveness
The persistence API exists as a separate layer from the domain
model
┌──────┐┌────────────────────────────────┐
│ D ││ │
│ o ││ Presentation layer │
│ m ││ │
│ a │└────────────────────────────────┘
│ i │┌────────────────────────────────┐
│ n ││ │
│ ││ Service layer │
│ m ││ │
│ o │└────────────────────────────────┘
│ d │┌────────────────────────────────┐
│ e ││ │
│ l ││ Persistence layer │
│ ││ │
└──────┘└────────────────────────────────┘
Non-intrusiveness
That is, the persisted objects are not aware of the persistence layer
┌──────┐┌────────────────────────────────┐
│ D ││ │
│ o ││ Presentation layer │
│ m ││ │
│ a │└────────────────────────────────┘
│ i │┌────────────────────────────────┐
│ n ││ │
│ ││ Service layer │
│ m ││ │
│ o │└────────────────────────────────┘
│ d │┌────────────────────────────────┐
│ e ││ │
│ l ││ Persistence layer │
│ ││ │
└──────┘└────────────────────────────────┘
Object queries
JPA comes with an object-oriented query language that operates
on classes and objects, rather than tables and rows
SELECT c
FROM Category c
WHERE c.items is NOT EMPTY
En##es and EntityManager
En##es in the rela#onal paradigm
In the rela*onal paradigm, an en#ty is something that can be
recognized to have a7ributes and rela*onships
id departOn
● ○
│ │
┌───┴───────────┴─────┐
│ │ arriveOn
│ Flight │─────○
│ │
└─────────────────────┘
En##es in the rela#onal paradigm
An en%ty has an independent existence and can be uniquely
iden/fied
id departOn
● ○
│ │
┌───┴───────────┴─────┐
│ │ arriveOn
│ Flight │─────○
│ │
└─────────────────────┘
En##es in the rela#onal paradigm
An en%ty may par$cipate in rela$onships with any number of
other en%%es in a number of standard ways
+---------+ +---------+ +----------+
| | | | | |
| +-----> +------> |
| | | | | |
+---------+ +---------+ +----------+
Flight FlightLeg Airport
En##es in the OO paradigm
In the object-oriented paradigm, we would add behavior to an
en7ty and call it a class
public class Flight {
private List<FlightLeg> legs;
private BigDecimal totalCost;
public Flight(...) {...}
public boolean isNonStop() {...}
public long getTotalTravelTime() {...}
// other methods
}
The intui)on behind ORM
Hence, the intui%on behind object-rela2onal mapping is that
• Classes correspond to tables
• Objects correspond to tuples
En#ty classes
The @Entity annota)on is used to qualify a class as an en'ty
@Entity
public class Employee {
@Id private int id;
private String name;
private long salary;
public Employee() { ... }
// other methods (e.g., getters and setters)
}
En#ty classes
En#ty objects are just plain-old Java objects
Employee emp1 = new Employee(12, "Jon Snow");
Employee emp2 = new Employee(20, "Portgas D. Ace");
En#ty requirements
En##es must respect some requirements
• The en'ty class must have a public or protected default
constructor
• The en'ty class must not be final
En#ty requirements
En##es must respect some requirements
• No method or variables of the en3ty class may be final
• If an en3ty object is to be passed as a detached object, the
Serializable interface must be implemented
Persistence unit
We refer to the set of en(ty classes as the persistence unit
@Entity public class Employee { ... }
@Entity public class Department { ... }
@Entity public class ParkingSpace { ... }
EntityManager
EntityManager is the central authority for all persistence ac/ons
EntityManager
EntityManager provides methods for crea0ng queries, finding
objects, synchronizing, and inser0ng objects into the DB
EntityManager
The EntityManager API directly maps to CRUD opera8ons
• persist (INSERT)
• merge (UPDATE)
• remove (DELETE)
• find (SELECT)
Crea%ng a new en%ty
En#ty objects do not become persistent just by invoking the new
operator1
Employee e = new Employee(12, "Jon Snow”)
1
How would they auto-magically become persistent? A:er all, we said that en<<es objects are just POJOs
Crea%ng a new en%ty
Newly-created objects are in the transient state, since the
EntityManager does not know they exist yet
Employee e = new Employee(12, "Jon Snow")
Persis&ng an en&ty
En#ty objects remain transient un#l we no#fy the
EntityManager of their existence
Employee e = new Employee(12, "Jon Snow")
Persis&ng an en&ty
The persist() method no#fies the En+tyManager of the
existence of a given transient en+ty object2
Employee emp = new Employee(12, "Jon Snow");
entityManager.persist(emp);
2
Remembr that the persist() method does not actually cause the en3ty object to be immediately persisted, we
are just sending a no3fica3on to the EntityManager
Persis&ng an en&ty
The en&ty object enters the managed state
Employee emp = new Employee(12, "Jon Snow");
entityManager.persist(emp);
Persis&ng an en&ty
EntityManager makes sure that each managed object is
synchronized with the related database tuple
Employee emp = new Employee(12, "Jon Snow");
entityManager.persist(emp);
Persistence context
The set of managed objects is called the persistence context
┌─────────────────────────────┐
│ │
│ ● o1 │ ● o5
│ │
│ ● o4 │ ● o6
│ │
│ ● o2 │
│ ● o3 │ ● o7
│ │
└─────────────────────────────┘
Persistence context
Persistence context
EntityManger is the persistence context supervisor, whose
responsibility is to keep in sync managed objects with tuples
EntityManager
◊
│
┌──────────────────┼──────────┐
│ │ │
│ │ │
│ ● o1 │ ● o5
│ │
│ ● o4 │ ● o6
│ │
│ ● o2 │
│ ● o3 │ ● o7
│ │
└─────────────────────────────┘
Persistence context
Persistence context
Each EntityManager has its own persistence context, and there
may exist several EntityManagers at once
EntityManager A EntityManager B
◊ ◊
│ │
┌──────────────────┼──────────┐ ┌──────────────────┼──────────┐
│ │ │ │ │ │
│ │ │ │ │ │
│ ● o1 │ │ ● o5 │ ● o9
│ │ │ │
│ ● o4 │ │ ● o7 │ ● o8
│ │ │ │
│ ● o2 │ │ ● o6 │
│ ● o3 │ │ │ ● o10
│ │ │ │
└─────────────────────────────┘ └─────────────────────────────┘
Persistence context A Persistence context B
Finding an en)ty
The find() method finds en*ty objects by primary key
Employee emp = entityManager.find(Employee.class, 12);
Finding an en)ty
When the call completes, the returned en2ty object is in the
managed state
Employee emp = entityManager.find(Employee.class, 12);
Finding an en)ty
The find() method returns null if the en/ty cannot be found
Employee emp = entityManager.find(Employee.class, 12);
Removing an en+ty
The remove() method removes the data associated with an en/ty
object from the database
entityManager.remove(emp);
Removing an en+ty
The remove() method will also detach the en/ty object
entityManager.remove(emp);
Removing an en+ty
Once detached, an en+ty is no longer managed by the related
EntityManager, i.e., it is no longer part of its persistence context
entityManager.remove(emp);
Removing an en+ty
Since the related tuple is deleted, the en1ty objects enters the
removed state
entityManager.remove(emp);
Removing an en+ty
Removed en))es cannot be made managed again
entityManager.remove(emp);
En#ty’s lifecycle
+-------------+
| |
| Persisted |
| |
+------+------+
|
| find()/
| query
|
+-------------+ +------v-------+ +-----------+
new | | persist() | | remove() | |
+----------> Transient +-------------> Managed +------------> Removed |
| | | | | |
+-------------+ +---+------^---+ +-----------+
| |
out of scope/ | | merge()/
serialized/ | | refresh()
cloned | |
| |
+---v------+---+
| |
| Detached |
| |
+--------------+
Iden%fier genera%on
Some%mes, applica%ons do not want to explicitly manage
uniqueness in some aspect of their domain model
Iden%fier genera%on
The persistence provider can automa&cally generate an iden0fier
for every en0ty object of a given type
Iden%fier genera%on
This persistence provider’s feature is called iden%fier genera%on
and is specified by the @GeneratedValue annota7on
@Entity
public class Employee {
    @Id @GeneratedValue
    private int id;
    ...
}
Iden%fier genera%on
Applica'ons can choose one out of four genera*on strategies
┌──────────────────────────────┬─────────────────────────────────────────┐
│/// Id generation strategy ///│////////////// Description /////////////│
├──────────────────────────────┼─────────────────────────────────────────┤
│ │The provider generates identifiers by │
│ AUTO │using whatever strategy it wants │
│ │ │
├──────────────────────────────┼─────────────────────────────────────────┤
│ │Identifiers are generated according to a │
│ TABLE │generator table │
│ │ │
├──────────────────────────────┼─────────────────────────────────────────┤
│ │If the underlying DB supports sequences, │
│ SEQUENCE │the provider will use this feature for │
│ │generating ids │
├──────────────────────────────┼─────────────────────────────────────────┤
│ │If the underlying DB supports primary key│
│ IDENTITY │identity columns, the provider will use │
│ │this feature for generating ids │
└──────────────────────────────┴─────────────────────────────────────────┘
AUTO strategy
Remember that the AUTO mode is a genera0on strategy mainly
meant for developing prototypes
@Entity
public class Employee {
    @Id @GeneratedValue(strategy=GenerationType.AUTO)
    private int id;
    ...
}
AUTO strategy
In any other situa.on, it would be be4er to use other genera.on
strategies
@Entity
public class Employee {
    @Id @GeneratedValue(strategy=GenerationType.AUTO)
    private int id;
    ...
}
Integra(ng JPA into Spring
Required steps
To use JPA in our Spring Web applica5on we need to
1. Define a data source
2. Understand how to produce EntityManager instances
3. Introduce transac8onal seman8cs into the service layer
4. Write JPA-based repository beans
1. Defining a data source
Data source
Regardless of the persistence framework, we need to configure a
reference to a data source
Pooled data source
When developing mul/threading applica/ons, the common
recommenda/on is to use a pooled data source
Pooled data source
A pooled data source is a data source that draws its connec2ons
from a connec%on pool
Pooled data source
Unfortunately, Spring does not provide a na5ve pooled data source
Pooled data source
We will use the pooled data source coming from the Apache
Database Connec/on Pooling (DBCP) project
Declaring the data source
By altering dataSource-context.xml, we can declare the new
data source as a bean in the back-end container
<bean id="dataSource"
class="org.apache.commons.dbcp2.BasicDataSource">
<property name="driverClassName" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://server:3306/db_schema"/>
<property name="username" value=”dbuser"/>
<property name="password" value=”dbpassword"/>
</bean>
Declaring the data source
BasicDataSource is the class implemen-ng the pooled data
source
<bean id="dataSource"
class="org.apache.commons.dbcp2.BasicDataSource">
<property name="driverClassName" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://server:3306/db_schema"/>
<property name="username" value=”dbuser"/>
<property name="password" value=”dbpassword"/>
</bean>
Declaring the data source
com.mysql.jdbc.Driver is the class implemen-ng the JDBC
driver
<bean id="dataSource"
class="org.apache.commons.dbcp2.BasicDataSource">
<property name="driverClassName" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://server:3306/db_schema"/>
<property name="username" value=”dbuser"/>
<property name="password" value=”dbpassword"/>
</bean>
Maven dependencies
As usual, we can use Maven to automa1cally resolve dependencies
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-dbcp2</artifactId>
<version>2.1.1</version>
</dependency>
Maven dependencies
As usual, we can use Maven to automa1cally resolve dependencies
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.38</version>
</dependency>
2. Obtaining an EntityManager
Obtaining an EntityManager
Although we discussed the role of EntityManager, we s2ll do
not know how to obtain an EntityManager instance
Obtaining an EntityManager
The JPA specifica.on defines two kinds of EntityManagers
• Applica(on-managed
• Container-managed
Applica'on-managed
Applica'on-managed EntityManagers are created by the
applica.on itself
EntityManagerFactory emf = Persistence.createEntityManagerFactory("MyPersistenceUnit");
EntityManager em = emf.createEntityManager();
Applica'on-managed
The applica*on is responsible for every aspect of the
EntityManager’s lifecycle
EntityManager em = emf.createEntityManager();
...
entityManager.close();
Applica'on-managed
The applica*on also needs to manually manage transac'ons
entityManager.getTransaction().begin();
entityManager.getTransaction().commit();
Applica'on-managed
This kind of EntityManager is typical of JSE applica*ons
Container-managed
Container-managed EntityManagers are created by a container,
which also injects them into the applica5on components
EntityManager beans
Spring supports both types of EntityManager instances
EntityManager beans
• LocalEntityManagerFactoryBean for applica+on-managed
EntityManagers
• LocalContainerEntityManagerFactoryBean for
container-managed EntityManagers3
3
Actually, LocalEntityManagerFactoryBean (resp. LocalContainerEntityManagerFactoryBean)
produces applica5on-managed (resp. container-managed) EntityManagerFactorys, which will in turn produce
applica5on-managed (resp. container-managed) EntityManagers
EntityManager beans
The following declares a factory bean for container-managed
EntityManagers in dataSource-context.xml
<bean id="emf"
class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="dataSource" ref="dataSource"/>
<property name="packagesToScan" value="it.polimi.awt.springmvc.domain"/>
<property name="persistenceUnitName" value=”MyPersistenceUnit"/>
...
</bean>
EntityManager beans
dataSource is the data source bean we previously declared
<bean id="emf"
class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="dataSource" ref="dataSource"/>
<property name="packagesToScan" value="it.polimi.awt.springmvc.domain"/>
<property name="persistenceUnitName" value=”MyPersistenceUnit"/>
...
</bean>
EntityManager beans
it.polimi.awt.springmvc.domain is the package containing
the classes to be persisted
<bean id="emf"
class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="dataSource" ref="dataSource"/>
<property name="packagesToScan" value="it.polimi.awt.springmvc.domain"/>
<property name="persistenceUnitName" value=”MyPersistenceUnit"/>
...
</bean>
EntityManager beans
MyPersistenceUnit is the name of the persistence unit
<bean id="emf"
class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="dataSource" ref="dataSource"/>
<property name="packagesToScan" value="it.polimi.awt.springmvc.domain"/>
<property name="persistenceUnitName" value=”MyPersistenceUnit"/>
</bean>
Persistence provider
Several possible JPA implementa3ons can be used as the
persistence provider
• EclipseLink
• Hibernate
• OpenJPA
• TopLink
Persistence provider
One way to tell Spring which implementa3on to use is to declare a
JpaVendorAdapter bean in dataSource-context.xml
<bean id="jpaVendorAdapter"
class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
<property name="database" value="MYSQL"/>
</bean>
Persistence provider
Specifically, we use HibernateJpaVendorAdapter to denote
that Hibernate is our persistence provider
<bean id="jpaVendorAdapter"
class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
<property name="database" value="MYSQL"/>
</bean>
Persistence provider
We set the database property to MYSQL to denote that MySQL is
the underlying RDBMS
<bean id="jpaVendorAdapter"
class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
<property name="database" value="MYSQL"/>
</bean>
Persistence provider
We can now set-inject our JpaVendorAdapter bean into the
LocalContainerEntityManagerFactoryBean:
<bean id="emf"
class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="dataSource" ref="dataSource"/>
<property name="packagesToScan" value="it.polimi.awt.springmvc.domain"/>
<property name="persistenceUnitName" value=”MyPersistenceUnit"/>
<property name="jpaVendorAdapter" ref="jpaVendorAdapter"/>
</bean>
Maven dependencies
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-orm</artifactId>
<version>4.2.5.RELEASE</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-entitymanager</artifactId>
<version>5.1.0.Final</version>
</dependency>
<dependency>
<groupId>org.jboss.logging</groupId>
<artifactId>jboss-logging</artifactId>
<version>3.3.0.Final</version>
</dependency>
Alterna(ves exist
No#ce we managed to integrate JPA in Spring by solely adding
beans into the back-end container
persistence.xml
That is, we did not have to introduce the standard JPA deployment
descriptor file persistence.xml
persistence.xml
<persistence>
<persistence-unit name="MyPersistenceUnit">
<provider>org.hibernate.ejb.HibernatePersistence</provider>
<properties>
<property name="javax.persistence.jdbc.driver"
value="com.mysql.jdbc.Driver"/>
<property name="javax.persistence.jdbc.url"
value="jdbc:mysql://serverurl:3306/db-schema"/>
<property name="javax.persistence.jdbc.user"
value="dbuser"/>
<property name="javax.persistence.jdbc.password"
value="dbpasswd"/>
</properties>
</persistence-unit>
</persistence>
3. Dealing with transac1ons
Transac'ons
In so&ware, all-or-nothing opera3ons are called transac'ons
Everything goes well
+------------------->
+-----------------------+ |
| | |
| 1. Verify seats | |
Purchase ticket | 2. Reserve seat | |
+-----------------------> 3. Receive payment +----+
| 4. Issue ticket | |
| | |
+-----------------------+ |
+-------------------->
Something goes wrong
Transac'ons
Transac'ons allow grouping several opera'ons into a single unit of
work that either fully happens or fully does not happen
Everything goes well
+------------------->
+-----------------------+ |
| | |
| 1. Verify seats | |
Purchase ticket | 2. Reserve seat | |
+-----------------------> 3. Receive payment +----+
| 4. Issue ticket | |
| | |
+-----------------------+ |
+-------------------->
Something goes wrong
Transac'onal boundary
The service layer is the transac'onal boundary of the applica1on
┌──────┐┌────────────────────────────────┐
│ D ││ │
│ o ││ Presentation layer │
│ m ││ │
│ a │└────────────────────────────────┘
│ i │╔════════════════════════════════╗
│ n │║ ║
│ │║ Service layer ║
│ m │║ ║
│ o │╚════════════════════════════════╝
│ d │┌────────────────────────────────┐
│ e ││ │
│ l ││ Persistence layer │
│ ││ │
└──────┘└────────────────────────────────┘
Transac'onal boundary
If a service method makes mul3ple calls against one or more
persistence beans, we want those calls to operate as part of a
single transac,on
Transac'onal boundary
To handle this, the service layer needs a way to embed its
persistence calls within the context of a transac,on
Transac'onal boundary
Transaction |
+-----------------------------------------------|-------------------------------------------------+
| | |
| | |
| +-----------------v-----------------+ |
| | | |
| | AccountService.transferFunds() | |
| | | |
| +-----------------+-----------------+ |
| | |
| | |
| | |
| | |
| +---------------------------------------------------------------+ |
| | | | |
| | | | |
| +------------v-----------+ +-----------v------------+ +-----------v-----------+ |
| | | | | | | |
| | AccountRepository | | AccountRepository | | LogRepository | |
| | .update(account1) | | .update(account2) | | .create(entry) | |
| | | | | | | |
| +------------------------+ +------------------------+ +-----------------------+ |
| |
| |
+-------------------------------------------------------------------------------------------------+
Transac'on managers
Spring does not directly manage transac1ons
Transac'on managers
Instead, it provides a selec1on of transac'on managers
• JpaTransactionManager
• JtaTransactionManager
• JdoTransactionManager
Transac'on managers
Each such transac+on manager acts as a façade to a pla2orm-
specific implementa+on
• JpaTransactionManager
• JtaTransactionManager
• JdoTransactionManager
Declaring a transac-on manager
The transac+on manager of interest needs to be declared in
dataSource-context.xml
<bean id=”transactionManager”
class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="emf"/>
</bean>
Declaring a transac-on manager
JpaTransactionManager needs to be wired to a
EntityManagerFactory
<bean id=”transactionManager”
class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="emf"/>
</bean>
Declaring a transac-on manager
JpaTransactionManager collaborates with the
EntityManager that is produced by the factory to conduct
transac4ons
<bean id=”transactionManager”
class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="emf"/>
</bean>
Two types of transac/ons
Spring provides two ways of specifying transac3ons
• Programma(c transac(ons
• Declara(ve transac(ons
Declara've transac'ons
Most Spring users choose declara've transac'on management, as
this op2on has the least impact on applica2on code
Declara've transac'ons
Declara've transac'ons allow keeping business code free from
repe$$ve transac$on demarca$on code
public void saveAccount(Account account) {
txTemplate.execute(new TransactionCallback<Void>() {
public void doInTransaction(TransactionStatus txStatus) {
try {
repository.saveAccount(account);
} catch (RuntimeException e) {
txStatus.setRollbackOnly();
throw e;
}
}
});
}
@Transactional
The @Transactional annota)on specifies that an interface,
class, or method must have transac'onal seman'cs
@Service
@Transactional
public class AccountServiceImpl implements AccountService { ... }
@Transactional
From this point on, opera/ons will be transac'onal
@Service
@Transactional
public class AccountServiceImpl implements AccountService { ... }
@Transactional
When needed, addi$onal transac-onal seman$cs can be specified
(e.g., marking the transac-ons as read-only)
@Service
@Transactional(readOnly = true)
public class AccountServiceImpl implements AccountService { ... }
Ac#vate declara#ve transac#ons
A simple addi+on to dataSource-context.xml allows
ac+va+ng declara+ve transac+ons
<tx:annotation-driven/>
Maven dependencies
As usual, we can use Maven to automa1cally resolve dependencies
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-tx</artifactId>
<version>4.2.5.RELEASE</version>
</dependency>
4. How to write JPA repository beans
Persistence context
Let us intend the persistence context as a cache
Persistence context
The objects we alter could then be intended as a in-memory copy
of the data in the database
Persistence context
Hence, by doing account.getBalance() we access the in-
memory object rather than taking the data from the database
Persistence context
Similarly, by doing account.setBalance(5000) we alter the
in-memory object, rather than the data on the database
Persistence context
At a certain point the persistence context needs to be flushed so as
to mirror the changes in the database
Within the same transac-on,
how many persistence contexts should exist?
One persistence context
In any given transac.on, we want exactly one persistence context
(i.e., cache) for a given set of data
Transaction |
+-----------------------------------------------|-------------------------------------------------+
| | |
| | |
| +-----------------v-----------------+ |
| | | |
| | AccountService.transferFunds() | |
| | | |
| +-----------------+-----------------+ |
| | |
| | |
| | |
| | |
| +---------------------------------------------------------------+ |
| | | | |
| | | | |
| +------------v-----------+ +-----------v------------+ +-----------v-----------+ |
| | | | | | | |
| | AccountRepository | | AccountRepository | | LogRepository | |
| | .update(account1) | | .update(account2) | | .create(entry) | |
| | | | | | | |
| +------------------------+ +------------------------+ +-----------------------+ |
| |
| |
+-------------------------------------------------------------------------------------------------+
One persistence context
By doing so, the different calls comprised in the transac3on will
interact with the same data
Transaction |
+-----------------------------------------------|-------------------------------------------------+
| | |
| | |
| +-----------------v-----------------+ |
| | | |
| | AccountService.transferFunds() | |
| | | |
| +-----------------+-----------------+ |
| | |
| | |
| | |
| | |
| +---------------------------------------------------------------+ |
| | | | |
| | | | |
| +------------v-----------+ +-----------v------------+ +-----------v-----------+ |
| | | | | | | |
| | AccountRepository | | AccountRepository | | LogRepository | |
| | .update(account1) | | .update(account2) | | .create(entry) | |
| | | | | | | |
| +------------------------+ +------------------------+ +-----------------------+ |
| |
| |
+-------------------------------------------------------------------------------------------------+
One persistence context
Therefore, we want exactly one EntityManger per transac3on, as
different EntitManagers correspond to different persistence
contexts
Persistence context propaga/on
We want to automa&cally propagate the same persistence context
to all the beans involved in the same transac5on
@Repository public class AccountRepositoryImpl implements AccountRepository {...}
@Repository public class LogRepositoryImpl implements LogRepository {...}
Persistence context propaga/on
This amounts to injec/ng the same EntityManager to all the
components involved
@Repository public class JpaAccountRepository implements AccountRepository {...}
@Repository public class JpaLogRepository implements LogRepository {...}
@PersistenceContext
The @PersistenceContext annota)on automa&cally
propagates the persistence context
@Repository
public class JpaAccountRepository implements AccountRepository {
@PersistenceContext
private EntityManager em;
@Override
public Account findById(int id) {
return em.find(Account.class, id);
}
}
Mapping rela+onships
En##es and rela#onships
If en&&es were isolated from one another, the issue of ORM would
be a trivial one
+------------+ +--------------+
| | | |
| Employee | | Department |
| | | |
+------------+ +--------------+
En##es and rela#onships
In reality, most en//es need to be able to have rela%onships with
other en//es
+------------+ +--------------+
| | | |
| Employee +-------------> Department |
| | * 1 | |
+------------+ +--------------+
En##es and rela#onships
This is what produces the domain model of the applica2on
+------------+ +--------------+
| | | |
| Employee +-------------> Department |
| | * 1 | |
+------------+ +--------------+
Rela%onships
Every rela)onship has four characteris-cs
• Direc'onality
• Role
• Cardinality
• Ownership
Direc&onality
Each en(ty in a rela(onship may have a pointer to the other en(ty
+------------+ +--------------+
| | | |
| Employee +-------------> Department |
| | * 1 | |
+------------+ +--------------+
Direc&onality
If only one en)ty has a pointer to the other, the rela)onship is said
to be unidirec(onal
+------------+ +--------------+
| | | |
| Employee +-------------> Department |
| | * 1 | |
+------------+ +--------------+
Direc&onality
When each en(ty points to the other, the rela(onship is said to be
bidirec'onal
+------------+ +--------------+
| | | |
| Employee <-------------> Department |
| | * 1 | |
+------------+ +--------------+
Direc&onality
All rela'onships in JPA are unidirec(onal. A bidirec'onal
rela'onship has to be intended as a pair of unidirec'onal mappings
+------------+ * 1 +--------------+
| +-------------> |
| Employee | | Department |
| <-------------+ |
+------------+ * 1 +--------------+
Role
Depending on the direc.onality, we can iden.fy the en.ty playing
the role of source and the en.ty playing the role of target
+------------+ +--------------+
| | | |
| Employee +-------------> Department |
| | * 1 | |
+------------+ +--------------+
Role
Employee and Department are involved in a unidirec(onal
rela(onship
+------------+ +--------------+
| | | |
| Employee +-------------> Department |
| | * 1 | |
+------------+ +--------------+
Role
Employee is the source en)ty
+------------+ +--------------+
| | | |
| Employee +-------------> Department |
| | * 1 | |
+------------+ +--------------+
Role
Department is the target en(ty
+------------+ +--------------+
| | | |
| Employee +-------------> Department |
| | * 1 | |
+------------+ +--------------+
Cardinality
Each role in the rela-onship has its own cardinality
• Many-to-one: many source en..es, one target en.ty
• One-to-many: one source en.ty, many target en..es
• One-to-one: one source en.ty, one target en.ty
• Many-to-many: many source en..es, many target en..es
Ownership
In the database, almost every rela2onship is implemented by
introducing a column that refers to a key in another table
Ownership
Such a column is usually called the join column
Ownership
The underlying Employee table has a join column containing the
Department primary key
┌─────────────┬───────────────┬─────────────┬──────────────┐
│ employeeId │ name │ gender │ departmentId │
├─────────────┼───────────────┼─────────────┼──────────────┤
│ 12 │ Jon Snow │ male │ 7 │
└─────────────┴───────────────┴─────────────┴──────────────┘
Ownership
The en&ty holding the join column is called the owner of the
rela&onship and its side is called the owning side
┌─────────────┬───────────────┬─────────────┬──────────────┐
│ employeeId │ name │ gender │ departmentId │
├─────────────┼───────────────┼─────────────┼──────────────┤
│ 12 │ Jon Snow │ male │ 7 │
└─────────────┴───────────────┴─────────────┴──────────────┘
Ownership
Employee is the owner of the rela,onship
+------------+ +--------------+
| | | |
| Employee +-------------> Department |
| | * 1 | |
+------------+ +--------------+
Many-to-one mappings
In a many-to-one mapping, the owner of the rela2onship is the
source en2ty
@Entity
public class Employee {
@Id private int id;
@ManyToOne
private Department department;
}
Many-to-one mappings
A many-to-one mapping is defined by annota2ng the source en)ty
with the @ManyToOne annota2on
@Entity
public class Employee {
@Id private int id;
@ManyToOne
private Department department;
}
One-to-many mappings
In a one-to-many mapping, the owner of the rela2onship is the
target en2ty
@Entity
public class Department {
@Id private int id;
@OneToMany(mappedBy="department")
private List<Employee> employees;
}
One-to-many mappings
Therefore, the @OneToMany annota,on must come with the
mappedBy a3ribute
@Entity
public class Department {
@Id private int id;
@OneToMany(mappedBy="department")
private List<Employee> employees;
}
One-to-many mappings
The mappedBy a&ribute indicates that the owning side resides at
the other end of the rela5onship
@Entity
public class Department {
@Id private int id;
@OneToMany(mappedBy="department")
private List<Employee> employees;
}
One-to-one mappings
In a one-to-one mapping, the owner can be either the source or
the target en4ty
@Entity
public class Employee {
@Id private int id;
@OneToOne
private ParkingSpace parkingSpace;
}
One-to-one mappings
A one-to-one mapping is defined by annota2ng the owner en'ty
with the @OneToOne annota2on
@Entity
public class Employee {
@Id private int id;
@OneToOne
private ParkingSpace parkingSpace;
}
One-to-one mappings
If the one-to-one mapping is bidirec4onal, the inverse side of the
rela4onship needs to be specified as well
@Entity
public class ParkingSpace {
@Id private int id;
@OneToOne(mappedBy="parkingSpace")
private Employee employee;
}
One-to-one mappings
In the non-owner en+ty, the @OneToOne annota+ons must come
with the mappedBy element
@Entity
public class ParkingSpace {
@Id private int id;
@OneToOne(mappedBy="parkingSpace")
private Employee employee;
}
Many-to-many mappings
In a many-to-many mapping there is no join column. The only way
to implement such a mapping is by means of a join table
┌─────────────┬─────────────┐
│ employeeId │ projectId │
├─────────────┼─────────────┤
│ 12 │ 7 │
├─────────────┼─────────────┤
│ 1 │ 33 │
├─────────────┼─────────────┤
│ 76 │ 7 │
└─────────────┴─────────────┘
Many-to-many mappings
Therefore, we can arbitrarily specify as owner either the source or
the target en6ty
@Entity
public class Employee {
@Id private int id;
@ManyToMany
private List<Project> projects;
}
Many-to-many mappings
If the many-to-many mapping is bidirec5onal, the inverse side of
the rela5onship needs to be specified as well
@Entity
public class Project {
@Id private int id;
@ManyToMany(mappedBy="projects")
private List<Employee> employees;
}
Many-to-many mappings
In the non-owner en+ty, the @ManyToMany annota+on must come
with the mappedBy element
@Entity
public class Project {
@Id private int id;
@ManyToMany(mappedBy="projects")
private List<Employee> employees;
}
Cascading opera.ons
By default, every EntityManager’s opera2on applies only to the
en2ty object supplied as the opera2on argument
Cascading opera.ons
The opera)on will not cascade to other en))es that have a
rela)onship with the en)ty that is being operated on
Cascading opera.ons
For some opera*ons, this is usually the desired behavior
// we do not want to also delete her department
entityManager.remove(employ);
Cascading opera.ons
For some other opera,ons, this is instead an unfortunate
circumstances
// we want to persist also the related department
entityManager.persist(employ);
Cascading opera.ons
If a transient en+ty has a rela+onship with another transient en+ty,
the two must be persisted together
Manually cascading
A naive approach would be to manually cascade related en33es
Employee emp = new Employee(...);
Department dep = new Department(...);
emp.setDepartment(dep);
entityManager.persist(dep);
entityManager.persist(emp);
Manually cascading
This is however inconvenient
Employee emp = new Employee(...);
Department dep = new Department(...);
emp.setDepartment(dep);
entityManager.persist(dep);
entityManager.persist(emp);
Manually cascading
We do not want to explicitly persist the Department instance
Employee emp = new Employee(...);
Department dep = new Department(...);
emp.setDepartment(dep);
entityManager.persist(dep);
entityManager.persist(emp);
Cascading opera.ons
The cascade a&ribute allows defining when opera5ons such as
persist() should be automa&cally cascaded across rela5onships
@Entity
public class Employee {
@ManyToOne(cascade=CascadeType.PERSIST)
Department department;
}
Cascading opera.ons
The cascade a&ribute allows defining when opera5ons such as
persist() should be automa&cally cascaded across rela5onships
Employee emp = new Employee(...);
Department dep = new Department(...);
emp.setDepartment(dep);
entityManager.persist(emp); // dep gets persisted as well
Cascading opera.ons
You need to be sure that the Department instance has been set
on the Employee instance before persist()-ing the la4er
Employee emp = new Employee(...);
Department dep = new Department(...);
emp.setDepartment(dep);
entityManager.persist(emp); // dep gets persisted as well
Cascading opera.ons
The cascade a&ribute accepts several possible values coming
from the CascadeType enumera4on
• PERSIST, REFRESH, REMOVE, MERGE and DETACH
Cascading opera.ons
The constant ALL is a shorthand for declaring that all five
opera4ons should be cascaded
@Entity
public class Employee {
@ManyToOne(cascade=CascadeType.ALL)
Department department;
}
Cascading opera.ons
As with rela,onships, cascade se3ngs are unidirec(onal
@Entity
public class Employee {
@Id private int id;
@ManyToOne(cascade=CascadeType.PERSIST)
Department department;
}
@Entity
public class Department {
@Id private int id;
@OneToMany(cascade=CascadeType.PERSIST, mappedBy="department")
private List<Employee> employees;
}
Cascading opera.ons
They must be explicitly set on both sides of a rela3onship if the
same behavior is intended for both situa3ons
@Entity
public class Employee {
@Id private int id;
@ManyToOne(cascade=CascadeType.PERSIST)
Department department;
}
@Entity
public class Department {
@Id private int id;
@OneToMany(cascade=CascadeType.PERSIST, mappedBy="department")
private List<Employee> employees;
}
Lazy loading
In many real situa.ons, certain por.ons of an en.ty will be seldom
accessed
+------------+ +--------------+
| | | |
| Employee <-------------> Department |
| | * 1 | |
+------------+ +--------------+
Lazy loading
Lazy loading is a design pa*ern that allows deferring the fetching
of data un4l they are actually needed
Lazy loading
The employees a&ribute may not be loaded each 3me a
Department is loaded
@Entity
public class Department {
@Id private int id;
@OneToMany(fetch=FetchType.LAZY, ...)
private List<Employee> employees;
}
Lazy loading
Lazy loading can improve performance because of the reduced
amount of SQL that gets executed
Lazy loading
In case of bidirec.onal rela.onships, the fetch mode might be lazy
on one side but eager on the other
@Entity
public class Employee {
@Id private int id;
@ManyToOne
Department department;
}
@Entity
public class Department {
@Id private int id;
@OneToMany(mappedBy="department", fetch=FetchType.LAZY)
private List<Employee> employees;
}
Lazy loading
As a ma&er of fact, rela/onships are o4en accessed in different
ways depending on the direc/on from which naviga/on occurs
@Entity
public class Employee {
@Id private int id;
@ManyToOne
Department department;
}
@Entity
public class Department {
@Id private int id;
@OneToMany(mappedBy="department", fetch=FetchType.LAZY)
private List<Employee> employees;
}
Lazy loading
Note that the direc,ve to lazily fetch an a/ribute is meant only to
be a hint to the persistence provider
@Entity
public class Department {
@Id private int id;
@OneToMany(fetch=FetchType.LAZY, ...)
private List<Employee> employees;
}
Lazy loading
The provider is not required to honor the request, as the behavior
of the en4ty is not compromised if data get eagerly loaded
@Entity
public class Department {
@Id private int id;
@OneToMany(fetch=FetchType.LAZY, ...)
private List<Employee> employees;
}
Lazy loading
The converse is not true: specifying that an a3ribute be eagerly
fetched might be cri9cal to access the en9ty once detached
@Entity
public class Employee {
@Id private int id;
@ManyToOne
Department department;
}
Querying the data source
Querying the data source
JPA provides three methods to retrieve en11es
• EntityManager.find()
• Query API
• Criteria API
Query API
Java Persistence Query Language
The Java Persistence Query Language (JPQL) is a pla0orm-
independent object-oriented query language defined as part of the
JPA specificaBon
Java Persistence Query Language
The main difference with SQL is that
• JPQL operates on classes and objects
• SQL operates on tables, columns and rows
Java Persistence Query Language
Therefore, the outcome of a JPQL query is a collec%on of objects,
rather than a list of tuples
Java Persistence Query Language
Note that JPQL syntax looks like SQL, but JPQL is not SQL
SELECT e FROM Employee e
JQPL statements
JPQL supports three types of statements
• SELECT statements retrieve en,,es or en,ty-related data
• UPDATE statements update one or more en,,es
• DELETE statements delete one or more en,,es
FROM clause
The FROM clause defines the domain for the query, that is, the
en55es that will be used in the query
SELECT e FROM Employee e
FROM clause
Employee is the domain that we want to query, and e is intended
as an iden(fier of type Employee
SELECT e FROM Employee e
FROM clause
Iden%fiers can be used in other clauses of the same query (e.g.,
WHERE clauses)
SELECT e
FROM Employee e
WHERE e.name = "Jon Snow"
Path Expressions
Given an iden)fier, we can use dot nota'on to access a specific
field of the en)ty
SELECT e
FROM Employee e
WHERE e.phones is NOT EMPTY
Path Expressions
Such expressions are known as path expressions
SELECT e
FROM Employee e
WHERE e.phones is NOT EMPTY
Path Expressions
Path expressions are commonly used in
• WHERE clauses so as to narrow the domain for a query
• ORDER BY clauses so as to order the retrieved result set
JOIN operator
In many common situa-ons, there is the need to join two or more
en--es based on their rela-onship
JOIN operator
To this end, joins can be specified either in the WHERE clause...
SELECT p.number
FROM Employee e, Phone p
WHERE e = p.employee AND e.department.name = 'NA42'
JOIN operator
...or in the FROM clause by means of the JOIN operator
SELECT p.number
FROM Employee e JOIN e.phones p
WHERE e.department.name = 'NA42'
Query API
JPQL queries are executed by means of the Query API
Query API
The required steps to create a JPA query are similar to those of a
tradi7onal JDBC query
┌────────────────────────────────┬─────────────────────────────────────────┐
│///////////// JDBC /////////////│/////////////// Query API //////////////│
├────────────────────────────────┼─────────────────────────────────────────┤
│ Obtain a database connection │ Obtain an EntityManager instance │
├────────────────────────────────┼─────────────────────────────────────────┤
│ Create a query statement │ Create a query statement │
├────────────────────────────────┼─────────────────────────────────────────┤
│ Execute the query │ Execute the query │
├────────────────────────────────┼─────────────────────────────────────────┤
│ Retrieve the result (tuples) │ Retrieve the result (objects) │
└────────────────────────────────┴─────────────────────────────────────────┘
Query API
The Query API supports two types of queries
• Named queries, which are meant to be stored and reused
• Dynamic queries, which are created and executed on the fly
Named query
Named query are stored on the en'ty
@Entity
@NamedQuery(
name = "findSalaries",
query = "SELECT e.salary FROM Employee")
public class Employee { ... }
Named query
Any query that is used in mul$ple components of the applica4on is
a candidate for a named query
@Entity
@NamedQuery(
name = "findSalaries",
query = "SELECT e.salary FROM Employee")
public class Employee { ... }
Named query
Named queries can enhance performance because they are
prepared once and then efficiently reused
@Entity
@NamedQuery(
name = "findSalaries",
query = "SELECT e.salary FROM Employee")
public class Employee { ... }
Named query
Named query are globally scoped and instan/ated by name
TypedQuery<Integer> query = entityManager
.createNamedQuery("findSalaries");
Named query
That is, named query instances can be created from any
component that can access the persistence unit
TypedQuery<Integer> query = entityManager
.createNamedQuery("findSalaries");
Named query
Consequently, a named queries must have a unique name in the
whole persistence unit
@Entity
@NamedQuery(name = "findSalaries", query = "...")
public class Employee { ... }
Dynamic query
Dynamic queries are created at run 0me, and they are normally
used when the query depends on the context
String stmt = "SELECT e FROM Employee e WHERE e.name = :empName";
TypedQuery<Employee> query = entityManager.createQuery(stmt);
Dynamic query
A dynamic query can be created wherever the EntityManager is
available. The only requirement is to pass a valid JPQL statement
String stmt = "SELECT e FROM Employee e WHERE e.name = :empName";
TypedQuery<Employee> query = entityManager.createQuery(stmt);
Execu&ng queries
A TypedQuery object represents a query instance
String stmt = "SELECT e FROM Employee e WHERE e.name = :empName";
TypedQuery<Employee> query = entityManager.createQuery(stmt);
Execu&ng queries
The TypedQuery interface defines several methods for
parameterizing and execu.ng the query
┌────────────────────────────────────────────┬─────────────────────────────────────────┐
│///////////// Method signature /////////////│////////////// Description //////////////│
├────────────────────────────────────────────┼─────────────────────────────────────────┤
│ public List getResultList(); │ Retrieves the result set │
├────────────────────────────────────────────┼─────────────────────────────────────────┤
│ public │ Sets the maximum number of objects to be│
│ TypedQuery<T> setMaxResults(int maxResult);│ retrieved │
├────────────────────────────────────────────┼─────────────────────────────────────────┤
│ public │ │
│ TypedQuery<T> setParameter(int position, │ Sets the value for a positional │
│ Object value); │ parameter │
│ │ │
├────────────────────────────────────────────┼─────────────────────────────────────────┤
│ public │ │
│ TypedQuery<T> setParameter(String name, │ Sets the value for a named parameter │
│ Object value); │ │
└────────────────────────────────────────────┴─────────────────────────────────────────┘
Parameters
The number of en,,es retrieved in a query may be limited by
specifying a WHERE clause, which can be parameterized
SELECT e.salary
FROM Employee e
WHERE e.name = :empName
Parameters
In JPA, There exist two types of parameters
• Posi&onal parameters
• Named parameters
Parameters
Before execu*ng a query, all parameters need to be set
SELECT e.salary
FROM Employee e
WHERE e.name = :empName
Parameters
This can be done using the TypedQuery’s setParameter()
method
SELECT e.salary
FROM Employee e
WHERE e.name = :empName
Posi%onal parameters
Posi%onal parameters are iden(fied by number
String stmt = "SELECT i FROM Item i WHERE i.initialPrice = ?1";
TypedQuery<Item> query = em.createQuery(stmt);
query.setParameter(1, 100.00);
List<Item> items = query.getResultList();
Named parameters
Named parameters are iden(fied by label
String stmt = "SELECT i FROM Item i WHERE i.initialPrice = :price";
TypedQuery<Item> query = em.createQuery(stmt);
query.setParameter("price", 100.00);
List<Item> items = query.getResultList();
Criteria API
The problem with the Query API
The Query API cannot verify the correctness of a JPQL query
before its actual execu:on
// This will compile despite the incorrect JQPL query
TypedQuery<Employee> query = em.createQuery("SELECT e FROM Employee t");
The problem with the Query API
We would much prefer to let the compila(on fail in the presence
of incorrect JQPL queries
Criteria API
The Criteria API provides a way of crea6ng type-safe queries, i.e.,
queries the compiler can check at compile-2me
Crea%ng a new query
The steps for crea-ng a Criteria API-based query are
1. Obtaining a CriteriaBuilder object
2. Using this instance to compose a CriteriaQuery object
3. Execu9ng the query
Crea%ng a new query
The CriteriaQuery instance represents the query we would like
to execute
Crea%ng a new query
The CriteriaBuilder interface provides methods for all
keywords, operators, and func8ons from JPQL
public interface CriteriaBuilder {
CriteriaQuery<T> createQuery(Class<T> resultClass);
Predicate and(Expression<Boolean> x, Expression<Boolean> y);
Predicate or(Expression<Boolean> x, Expression<Boolean> y);
Predicate isNotNull(Expression<?> x);
...
}
Crea%ng a new query
That is, the CriteriaBuilder is a factory for all the individual
pieces of the query
public interface CriteriaBuilder {
CriteriaQuery<T> createQuery(Class<T> resultClass);
Predicate and(Expression<Boolean> x, Expression<Boolean> y);
Predicate or(Expression<Boolean> x, Expression<Boolean> y);
Predicate isNotNull(Expression<?> x);
...
}
Crea%ng a new query
A CriteriaBuilder object can be obtained from an
EntityManager instance
CriteriaBuilder cb = entityManager.getCriteriaBuilder();
Crea%ng a new query
Once available, a CriteraBuilder can be used to create
CriteriaQuery objects
CriteriaQuery<Employee> c = cb.createQuery(Employee.class);
Crea%ng a new query
To ensure type-safety, the CriteriaQuery's type parameter
should be set to the result type of the query
CriteriaBuilder cb = entityManager.getCriteriaBuilder();
CriteriaQuery<Employee> c = cb.createQuery(Employee.class);
Root object
Every CriteriaQuery defines at least one Root object, whose
role is analogous to that of an iden%fier in a JPQL query
Root<Employee> e = c.from(Employee.class);
c.select(e);
Root object
Every CriteriaQuery defines at least one Root object, whose
role is analogous to that of an iden%fier in a JPQL query
SELECT e
FROM Employee e
Root object
Like JPQL iden+fiers, Root objects are commonly used in SELECT
and WHERE clauses
Root<Employee> e = c.from(Employee.class);
c.select(e);
Canonical metamodel
The Criteria API ensures type-safety by means of a canonical
metamodel
@StaticMetamodel(Employee.class) public class Employee_ {...}
@StaticMetamodel(Department.class) public class Department_ {...}
@StaticMetamodel(Project.class) public class Project_ {...}
Canonical metamodel
The canonical metamodel of a persistence unit is a descrip1on of
the persistent type, state, and rela1onships of en11es
@StaticMetamodel(Employee.class) public class Employee_ {...}
@StaticMetamodel(Department.class) public class Department_ {...}
@StaticMetamodel(Project.class) public class Project_ {...}
Canonical metamodel
In prac(ce, the canonical metamodel is implemented as a series of
classes that mirror the en((es in the domain model
@StaticMetamodel(Employee.class) public class Employee_ {...}
@StaticMetamodel(Department.class) public class Department_ {...}
@StaticMetamodel(Project.class) public class Project_ {...}
Canonical metamodel
Such metamodel classes provide access to metadata about the
associated domain class
@StaticMetamodel(Employee.class)
public class Employee_ {
public static volatile SingularAttribute<Employee, Integer> id;
public static volatile SingularAttribute<Employee, String> name;
public static volatile SingularAttribute<Employee, String> salary;
public static volatile SingularAttribute<Employee, Department> dept;
public static volatile SingularAttribute<Employee, Address> address;
public static volatile CollectionAttribute<Employee, Project> project;
}
Canonical metamodel
For each en*ty E, there should exist a metamodel class E_ in the
same package
@StaticMetamodel(Employee.class)
public class Employee_ {
public static volatile SingularAttribute<Employee, Integer> id;
public static volatile SingularAttribute<Employee, String> name;
public static volatile SingularAttribute<Employee, String> salary;
public static volatile SingularAttribute<Employee, Department> dept;
public static volatile SingularAttribute<Employee, Address> address;
public static volatile CollectionAttribute<Employee, Project> project;
}
Canonical metamodel
Each metamodel class must be annotated with the
@StaticMetamodel annota2on
@StaticMetamodel(Employee.class)
public class Employee_ {
public static volatile SingularAttribute<Employee, Integer> id;
public static volatile SingularAttribute<Employee, String> name;
public static volatile SingularAttribute<Employee, String> salary;
public static volatile SingularAttribute<Employee, Department> dept;
public static volatile SingularAttribute<Employee, Address> address;
public static volatile CollectionAttribute<Employee, Project> project;
}
Path expressions
Root objects and metamodel classes are employed together to
form path expressions
Root<Employee> e = c.from(Employee.class);
c.select( e.get(Employee_.department).get(Department_.id) );
Path expressions
The Root object and the metamodel classes are employed together
to form path expressions
SELECT e.department.id
FROM Employee e
JOIN opera'on
Joins can be performed by calling the join() method on the Root
object
Root<Employee> e = c.from(Employee.class);
Join<Employee, Phone> p = e.join(Employee_.phones);
c.select(p.get(Phone_.number))
c.where(cb.equal(e.get(Employee_.name), "Jon Snow"));
JOIN opera'on
Joins can be performed by calling the join() method on the Root
object
SELECT p.number
FROM Employee e JOIN e.phones p
WHERE e.name = "Jon Snow"
JOIN opera'on
Note that the resul,ng Join object behaves like a Root object,
meaning that joins can be cascaded
WHERE clause
WHERE clauses can be used to narrow the result set
Root<Employee> e = c.from(Employee.class);
c.select(e);
c.where(cb.equal(e.get(Employee_.name), "Jon Snow"));
WHERE clause
WHERE clauses can be used to narrow the result set
SELECT e
FROM Employee e
WHERE e.name = "Jon Snow"
WHERE clause
Each condi*on in a WHERE clause is expressed as a Predicate
instance
// Incremental construction
Predicate predicates = cb.conjunction();
predicates = cb.and(predicates, cb.equal(e.get(Employee_.name), "Jon Snow"));
predicates = cb.and(predicates, cb.equal(e.get(Employee_.dept).get(Department_.id), 7));
c.where(predicates);
WHERE clause
Predicates can be combined by means of AND or OR operators
// Incremental construction
Predicate predicates = cb.conjunction();
predicates = cb.and(predicates, cb.equal(e.get(Employee_.name), "Jon Snow"));
predicates = cb.and(predicates, cb.equal(e.get(Employee_.dept).get(Department_.id), 7));
c.where(predicates);
WHERE clause
Predicates can be combined by means of AND or OR operators
// List-based construction
List<Predicate> predicates = new ArrayList<>();
predicates.add(cb.equal(e.get(Employee_.name), "Jon Snow"));
predicates.add(cb.equal(e.get(Employee_.dept).get(Department_.id), 7));
Predicate[] predArray = predicates.toArray(new Predicate[predicates.size()]);
c.where(cb.and(predArray));
WHERE clause
Predicates can be combined by means of AND or OR operators
SELECT e
FROM Employee e
WHERE e.name = "Jon Snow" AND
d.department.id = 7
Defining parameters
To parameterize queries using the Criteria API, a
ParameterExpression object must be created
ParameterExpression<String> deptName = cb.parameter(String.class, "deptName");
Execu&ng queries
Once the query is composed, it is possible to obtain a
TypedQuery object out of a CriteriaQuery object
TypedQuery<Employee> q = entityManager.createQuery(c);
Execu&ng queries
As with any TypedQuery, parameters need to be provided before
the actual execu9on
TypedQuery<Employee> q = em.createQuery(c);
q.setParameter("deptName", "NA42")
return q.getResultList();
References
References
• Java Community Process, JPA 2.1 specifica:on
• Hibernate Community Documenta:on, EntityManager
• Hibernate Community Documenta:on, Transac:ons and
Concurrency
• Wikipedia, Data Access Object
• SpringSource, Spring Framework Reference
References
• Hibernate Wiki, Data Access Objects
• Hibernate Wiki, Open Session in View pa9ern
• Hibernate Community Documenta>on, Metamodel
• Hibernate Community Documenta>on, Criteria Queries
• OpenJPA, JPA Concepts
References
• M. Keith, M. Schincariol, Pro JPA 2, Mastering The Java
Persistence API, Apress Media LLC
• D. Panda et al., EJB3 In AcCon, Manning PublicaCons
• C. Baver, G.King, Java Persistence With Hibernate, Manning
PublicaCons
• S. Guruzu, G. Mak, Hibernate Recipes - A Problem-SoluCon
Approach, Apress Media LLC
References
• A.L. Rubinger, B.Burke, Enterprise JavaBeans 3.1, O’Reilly Media
• R.M. Reese, EJB 3.1 Cookbook, Packt Publishing
• Craig Walls, Spring in AcGon (3rd EdiGon), Manning PublicaGons
• Willie Wheeler, Spring in PracGce, Manning PublicaGons
Topics not covered
• Physical annota.ons
• Cascading policies other than PERSIST
• Vender-based APIs (e.g., Hibernate APIs)
• Advanced JPQL and Criteria API-based queries
• Long units of work

Weitere ähnliche Inhalte

Was ist angesagt?

DISE - Windows Based Application Development in Java
DISE - Windows Based Application Development in JavaDISE - Windows Based Application Development in Java
DISE - Windows Based Application Development in JavaRasan Samarasinghe
 
Chapter 8 - Exceptions and Assertions Edit summary
Chapter 8 - Exceptions and Assertions  Edit summaryChapter 8 - Exceptions and Assertions  Edit summary
Chapter 8 - Exceptions and Assertions Edit summaryEduardo Bergavera
 
Unit I Advanced Java Programming Course
Unit I   Advanced Java Programming CourseUnit I   Advanced Java Programming Course
Unit I Advanced Java Programming Courseparveen837153
 
Booting into functional programming
Booting into functional programmingBooting into functional programming
Booting into functional programmingDhaval Dalal
 
Chapter 2 - Getting Started with Java
Chapter 2 - Getting Started with JavaChapter 2 - Getting Started with Java
Chapter 2 - Getting Started with JavaEduardo Bergavera
 
Chapter 7 - Defining Your Own Classes - Part II
Chapter 7 - Defining Your Own Classes - Part IIChapter 7 - Defining Your Own Classes - Part II
Chapter 7 - Defining Your Own Classes - Part IIEduardo Bergavera
 
Java fundamentals
Java fundamentalsJava fundamentals
Java fundamentalsHCMUTE
 
Javascript basic course
Javascript basic courseJavascript basic course
Javascript basic courseTran Khoa
 
Oo Design And Patterns
Oo Design And PatternsOo Design And Patterns
Oo Design And PatternsAnil Bapat
 
Core java concepts
Core java concepts Core java concepts
Core java concepts javeed_mhd
 
Lab #2: Introduction to Javascript
Lab #2: Introduction to JavascriptLab #2: Introduction to Javascript
Lab #2: Introduction to JavascriptWalid Ashraf
 
Static and Dynamic polymorphism in C++
Static and Dynamic polymorphism in C++Static and Dynamic polymorphism in C++
Static and Dynamic polymorphism in C++Anil Bapat
 
Basic Javascript
Basic JavascriptBasic Javascript
Basic JavascriptBunlong Van
 
Scala 3 by Example - Algebraic Data Types for Domain Driven Design - Part 2
Scala 3 by Example - Algebraic Data Types for Domain Driven Design - Part 2Scala 3 by Example - Algebraic Data Types for Domain Driven Design - Part 2
Scala 3 by Example - Algebraic Data Types for Domain Driven Design - Part 2Philip Schwarz
 

Was ist angesagt? (20)

DISE - Windows Based Application Development in Java
DISE - Windows Based Application Development in JavaDISE - Windows Based Application Development in Java
DISE - Windows Based Application Development in Java
 
Generics in java
Generics in javaGenerics in java
Generics in java
 
Chapter 8 - Exceptions and Assertions Edit summary
Chapter 8 - Exceptions and Assertions  Edit summaryChapter 8 - Exceptions and Assertions  Edit summary
Chapter 8 - Exceptions and Assertions Edit summary
 
Unit I Advanced Java Programming Course
Unit I   Advanced Java Programming CourseUnit I   Advanced Java Programming Course
Unit I Advanced Java Programming Course
 
Booting into functional programming
Booting into functional programmingBooting into functional programming
Booting into functional programming
 
Java Generics
Java GenericsJava Generics
Java Generics
 
Chapter 2 - Getting Started with Java
Chapter 2 - Getting Started with JavaChapter 2 - Getting Started with Java
Chapter 2 - Getting Started with Java
 
Chapter 7 - Defining Your Own Classes - Part II
Chapter 7 - Defining Your Own Classes - Part IIChapter 7 - Defining Your Own Classes - Part II
Chapter 7 - Defining Your Own Classes - Part II
 
Java fundamentals
Java fundamentalsJava fundamentals
Java fundamentals
 
Oops
OopsOops
Oops
 
Javascript basic course
Javascript basic courseJavascript basic course
Javascript basic course
 
Oo Design And Patterns
Oo Design And PatternsOo Design And Patterns
Oo Design And Patterns
 
Core java concepts
Core java concepts Core java concepts
Core java concepts
 
Clean coding-practices
Clean coding-practicesClean coding-practices
Clean coding-practices
 
Object oriented concepts
Object oriented conceptsObject oriented concepts
Object oriented concepts
 
Function overloading
Function overloadingFunction overloading
Function overloading
 
Lab #2: Introduction to Javascript
Lab #2: Introduction to JavascriptLab #2: Introduction to Javascript
Lab #2: Introduction to Javascript
 
Static and Dynamic polymorphism in C++
Static and Dynamic polymorphism in C++Static and Dynamic polymorphism in C++
Static and Dynamic polymorphism in C++
 
Basic Javascript
Basic JavascriptBasic Javascript
Basic Javascript
 
Scala 3 by Example - Algebraic Data Types for Domain Driven Design - Part 2
Scala 3 by Example - Algebraic Data Types for Domain Driven Design - Part 2Scala 3 by Example - Algebraic Data Types for Domain Driven Design - Part 2
Scala 3 by Example - Algebraic Data Types for Domain Driven Design - Part 2
 

Andere mochten auch

JPQL/ JPA Activity 3
JPQL/ JPA  Activity 3JPQL/ JPA  Activity 3
JPQL/ JPA Activity 3SFI
 
JPQL/ JPA Activity 2
JPQL/ JPA Activity 2JPQL/ JPA Activity 2
JPQL/ JPA Activity 2SFI
 
JPQL/ JPA Activity 1
JPQL/ JPA Activity 1JPQL/ JPA Activity 1
JPQL/ JPA Activity 1SFI
 
Patni Hibernate
Patni   HibernatePatni   Hibernate
Patni Hibernatepatinijava
 
Web Services Part 2
Web Services Part 2Web Services Part 2
Web Services Part 2patinijava
 
How to bake reactive behavior into your Java EE applications
How to bake reactive behavior into your Java EE applicationsHow to bake reactive behavior into your Java EE applications
How to bake reactive behavior into your Java EE applicationsOndrej Mihályi
 
FinelyMe-JustFit Intro
FinelyMe-JustFit IntroFinelyMe-JustFit Intro
FinelyMe-JustFit IntroCheng Ta Yeh
 
Continuous integration practices to improve the software quality
Continuous integration practices to improve the software qualityContinuous integration practices to improve the software quality
Continuous integration practices to improve the software qualityFabricio Epaminondas
 
Introduction to developing modern web apps
Introduction to developing modern web appsIntroduction to developing modern web apps
Introduction to developing modern web appsFabricio Epaminondas
 
Quickstart for continuous integration
Quickstart for continuous integrationQuickstart for continuous integration
Quickstart for continuous integrationFabricio Epaminondas
 
Java persistence api
Java persistence api Java persistence api
Java persistence api Luis Goldster
 
Spring 4. Part 1 - IoC, AOP
Spring 4. Part 1 - IoC, AOPSpring 4. Part 1 - IoC, AOP
Spring 4. Part 1 - IoC, AOPNakraynikov Oleg
 
20160523 hibernate persistence_framework_and_orm
20160523 hibernate persistence_framework_and_orm20160523 hibernate persistence_framework_and_orm
20160523 hibernate persistence_framework_and_ormKenan Sevindik
 

Andere mochten auch (20)

Ejb5
Ejb5Ejb5
Ejb5
 
JPQL/ JPA Activity 3
JPQL/ JPA  Activity 3JPQL/ JPA  Activity 3
JPQL/ JPA Activity 3
 
15 jpaql
15 jpaql15 jpaql
15 jpaql
 
15 jpa
15 jpa15 jpa
15 jpa
 
Working with jpa
Working with jpaWorking with jpa
Working with jpa
 
JPQL/ JPA Activity 2
JPQL/ JPA Activity 2JPQL/ JPA Activity 2
JPQL/ JPA Activity 2
 
JPQL/ JPA Activity 1
JPQL/ JPA Activity 1JPQL/ JPA Activity 1
JPQL/ JPA Activity 1
 
Patni Hibernate
Patni   HibernatePatni   Hibernate
Patni Hibernate
 
Web Services Part 2
Web Services Part 2Web Services Part 2
Web Services Part 2
 
How to bake reactive behavior into your Java EE applications
How to bake reactive behavior into your Java EE applicationsHow to bake reactive behavior into your Java EE applications
How to bake reactive behavior into your Java EE applications
 
FinelyMe-JustFit Intro
FinelyMe-JustFit IntroFinelyMe-JustFit Intro
FinelyMe-JustFit Intro
 
Continuous integration practices to improve the software quality
Continuous integration practices to improve the software qualityContinuous integration practices to improve the software quality
Continuous integration practices to improve the software quality
 
Introduction to developing modern web apps
Introduction to developing modern web appsIntroduction to developing modern web apps
Introduction to developing modern web apps
 
Quickstart for continuous integration
Quickstart for continuous integrationQuickstart for continuous integration
Quickstart for continuous integration
 
Java persistence api
Java persistence api Java persistence api
Java persistence api
 
Spring 4. Part 1 - IoC, AOP
Spring 4. Part 1 - IoC, AOPSpring 4. Part 1 - IoC, AOP
Spring 4. Part 1 - IoC, AOP
 
Gradle - Build System
Gradle - Build SystemGradle - Build System
Gradle - Build System
 
Java Persistence API
Java Persistence APIJava Persistence API
Java Persistence API
 
20160523 hibernate persistence_framework_and_orm
20160523 hibernate persistence_framework_and_orm20160523 hibernate persistence_framework_and_orm
20160523 hibernate persistence_framework_and_orm
 
Spring Boot Update
Spring Boot UpdateSpring Boot Update
Spring Boot Update
 

Ähnlich wie Java Persistence API

Software Uni Conf October 2014
Software Uni Conf October 2014Software Uni Conf October 2014
Software Uni Conf October 2014Nayden Gochev
 
Beyond design patterns phpnw14
Beyond design patterns   phpnw14Beyond design patterns   phpnw14
Beyond design patterns phpnw14Anthony Ferrara
 
Java for android developers
Java for android developersJava for android developers
Java for android developersAly Abdelkareem
 
Adding a modern twist to legacy web applications
Adding a modern twist to legacy web applicationsAdding a modern twist to legacy web applications
Adding a modern twist to legacy web applicationsJeff Durta
 
Open Problems in Automatically Refactoring Legacy Java Software to use New Fe...
Open Problems in Automatically Refactoring Legacy Java Software to use New Fe...Open Problems in Automatically Refactoring Legacy Java Software to use New Fe...
Open Problems in Automatically Refactoring Legacy Java Software to use New Fe...Raffi Khatchadourian
 
Java Programming for Designers
Java Programming for DesignersJava Programming for Designers
Java Programming for DesignersR. Sosa
 
Object Oriented Programming All Unit Notes
Object Oriented Programming All Unit NotesObject Oriented Programming All Unit Notes
Object Oriented Programming All Unit NotesBalamuruganV28
 
Introduction to JPA and Hibernate including examples
Introduction to JPA and Hibernate including examplesIntroduction to JPA and Hibernate including examples
Introduction to JPA and Hibernate including examplesecosio GmbH
 
Java and Java platforms
Java and Java platformsJava and Java platforms
Java and Java platformsIlio Catallo
 
object oriented programming(PYTHON)
object oriented programming(PYTHON)object oriented programming(PYTHON)
object oriented programming(PYTHON)Jyoti shukla
 

Ähnlich wie Java Persistence API (20)

Assessing Product Line Derivation Operators Applied to Java Source Code: An E...
Assessing Product Line Derivation Operators Applied to Java Source Code: An E...Assessing Product Line Derivation Operators Applied to Java Source Code: An E...
Assessing Product Line Derivation Operators Applied to Java Source Code: An E...
 
Java
JavaJava
Java
 
Data access
Data accessData access
Data access
 
Software Uni Conf October 2014
Software Uni Conf October 2014Software Uni Conf October 2014
Software Uni Conf October 2014
 
Beyond design patterns phpnw14
Beyond design patterns   phpnw14Beyond design patterns   phpnw14
Beyond design patterns phpnw14
 
Anti Object-Oriented Design Patterns
Anti Object-Oriented Design PatternsAnti Object-Oriented Design Patterns
Anti Object-Oriented Design Patterns
 
Proyect of english
Proyect of englishProyect of english
Proyect of english
 
Java for android developers
Java for android developersJava for android developers
Java for android developers
 
Hello java
Hello java   Hello java
Hello java
 
Hello Java-First Level
Hello Java-First LevelHello Java-First Level
Hello Java-First Level
 
Hello java
Hello java  Hello java
Hello java
 
Java basic
Java basicJava basic
Java basic
 
Adding a modern twist to legacy web applications
Adding a modern twist to legacy web applicationsAdding a modern twist to legacy web applications
Adding a modern twist to legacy web applications
 
Open Problems in Automatically Refactoring Legacy Java Software to use New Fe...
Open Problems in Automatically Refactoring Legacy Java Software to use New Fe...Open Problems in Automatically Refactoring Legacy Java Software to use New Fe...
Open Problems in Automatically Refactoring Legacy Java Software to use New Fe...
 
Java Programming for Designers
Java Programming for DesignersJava Programming for Designers
Java Programming for Designers
 
Object Oriented Programming All Unit Notes
Object Oriented Programming All Unit NotesObject Oriented Programming All Unit Notes
Object Oriented Programming All Unit Notes
 
Dev381.Pp
Dev381.PpDev381.Pp
Dev381.Pp
 
Introduction to JPA and Hibernate including examples
Introduction to JPA and Hibernate including examplesIntroduction to JPA and Hibernate including examples
Introduction to JPA and Hibernate including examples
 
Java and Java platforms
Java and Java platformsJava and Java platforms
Java and Java platforms
 
object oriented programming(PYTHON)
object oriented programming(PYTHON)object oriented programming(PYTHON)
object oriented programming(PYTHON)
 

Mehr von Ilio Catallo

C++ Standard Template Library
C++ Standard Template LibraryC++ Standard Template Library
C++ Standard Template LibraryIlio Catallo
 
Regular types in C++
Regular types in C++Regular types in C++
Regular types in C++Ilio Catallo
 
Resource wrappers in C++
Resource wrappers in C++Resource wrappers in C++
Resource wrappers in C++Ilio Catallo
 
Memory management in C++
Memory management in C++Memory management in C++
Memory management in C++Ilio Catallo
 
Operator overloading in C++
Operator overloading in C++Operator overloading in C++
Operator overloading in C++Ilio Catallo
 
Multidimensional arrays in C++
Multidimensional arrays in C++Multidimensional arrays in C++
Multidimensional arrays in C++Ilio Catallo
 
Pointers & References in C++
Pointers & References in C++Pointers & References in C++
Pointers & References in C++Ilio Catallo
 
Spring MVC - Wiring the different layers
Spring MVC -  Wiring the different layersSpring MVC -  Wiring the different layers
Spring MVC - Wiring the different layersIlio Catallo
 
Spring MVC - Web Forms
Spring MVC  - Web FormsSpring MVC  - Web Forms
Spring MVC - Web FormsIlio Catallo
 
Spring MVC - The Basics
Spring MVC -  The BasicsSpring MVC -  The Basics
Spring MVC - The BasicsIlio Catallo
 
Web application architecture
Web application architectureWeb application architecture
Web application architectureIlio Catallo
 
Introduction To Spring
Introduction To SpringIntroduction To Spring
Introduction To SpringIlio Catallo
 
Gestione della memoria in C++
Gestione della memoria in C++Gestione della memoria in C++
Gestione della memoria in C++Ilio Catallo
 
Puntatori e Riferimenti
Puntatori e RiferimentiPuntatori e Riferimenti
Puntatori e RiferimentiIlio Catallo
 
JSP Standard Tag Library
JSP Standard Tag LibraryJSP Standard Tag Library
JSP Standard Tag LibraryIlio Catallo
 
Internationalization in Jakarta Struts 1.3
Internationalization in Jakarta Struts 1.3Internationalization in Jakarta Struts 1.3
Internationalization in Jakarta Struts 1.3Ilio Catallo
 
Validation in Jakarta Struts 1.3
Validation in Jakarta Struts 1.3Validation in Jakarta Struts 1.3
Validation in Jakarta Struts 1.3Ilio Catallo
 
Introduction to Struts 1.3
Introduction to Struts 1.3Introduction to Struts 1.3
Introduction to Struts 1.3Ilio Catallo
 

Mehr von Ilio Catallo (20)

C++ Standard Template Library
C++ Standard Template LibraryC++ Standard Template Library
C++ Standard Template Library
 
Regular types in C++
Regular types in C++Regular types in C++
Regular types in C++
 
Resource wrappers in C++
Resource wrappers in C++Resource wrappers in C++
Resource wrappers in C++
 
Memory management in C++
Memory management in C++Memory management in C++
Memory management in C++
 
Operator overloading in C++
Operator overloading in C++Operator overloading in C++
Operator overloading in C++
 
Multidimensional arrays in C++
Multidimensional arrays in C++Multidimensional arrays in C++
Multidimensional arrays in C++
 
Arrays in C++
Arrays in C++Arrays in C++
Arrays in C++
 
Pointers & References in C++
Pointers & References in C++Pointers & References in C++
Pointers & References in C++
 
Spring MVC - Wiring the different layers
Spring MVC -  Wiring the different layersSpring MVC -  Wiring the different layers
Spring MVC - Wiring the different layers
 
Spring MVC - Web Forms
Spring MVC  - Web FormsSpring MVC  - Web Forms
Spring MVC - Web Forms
 
Spring MVC - The Basics
Spring MVC -  The BasicsSpring MVC -  The Basics
Spring MVC - The Basics
 
Web application architecture
Web application architectureWeb application architecture
Web application architecture
 
Introduction To Spring
Introduction To SpringIntroduction To Spring
Introduction To Spring
 
Gestione della memoria in C++
Gestione della memoria in C++Gestione della memoria in C++
Gestione della memoria in C++
 
Array in C++
Array in C++Array in C++
Array in C++
 
Puntatori e Riferimenti
Puntatori e RiferimentiPuntatori e Riferimenti
Puntatori e Riferimenti
 
JSP Standard Tag Library
JSP Standard Tag LibraryJSP Standard Tag Library
JSP Standard Tag Library
 
Internationalization in Jakarta Struts 1.3
Internationalization in Jakarta Struts 1.3Internationalization in Jakarta Struts 1.3
Internationalization in Jakarta Struts 1.3
 
Validation in Jakarta Struts 1.3
Validation in Jakarta Struts 1.3Validation in Jakarta Struts 1.3
Validation in Jakarta Struts 1.3
 
Introduction to Struts 1.3
Introduction to Struts 1.3Introduction to Struts 1.3
Introduction to Struts 1.3
 

Kürzlich hochgeladen

Judging the Relevance and worth of ideas part 2.pptx
Judging the Relevance  and worth of ideas part 2.pptxJudging the Relevance  and worth of ideas part 2.pptx
Judging the Relevance and worth of ideas part 2.pptxSherlyMaeNeri
 
ECONOMIC CONTEXT - PAPER 1 Q3: NEWSPAPERS.pptx
ECONOMIC CONTEXT - PAPER 1 Q3: NEWSPAPERS.pptxECONOMIC CONTEXT - PAPER 1 Q3: NEWSPAPERS.pptx
ECONOMIC CONTEXT - PAPER 1 Q3: NEWSPAPERS.pptxiammrhaywood
 
How to do quick user assign in kanban in Odoo 17 ERP
How to do quick user assign in kanban in Odoo 17 ERPHow to do quick user assign in kanban in Odoo 17 ERP
How to do quick user assign in kanban in Odoo 17 ERPCeline George
 
USPS® Forced Meter Migration - How to Know if Your Postage Meter Will Soon be...
USPS® Forced Meter Migration - How to Know if Your Postage Meter Will Soon be...USPS® Forced Meter Migration - How to Know if Your Postage Meter Will Soon be...
USPS® Forced Meter Migration - How to Know if Your Postage Meter Will Soon be...Postal Advocate Inc.
 
Incoming and Outgoing Shipments in 3 STEPS Using Odoo 17
Incoming and Outgoing Shipments in 3 STEPS Using Odoo 17Incoming and Outgoing Shipments in 3 STEPS Using Odoo 17
Incoming and Outgoing Shipments in 3 STEPS Using Odoo 17Celine George
 
Keynote by Prof. Wurzer at Nordex about IP-design
Keynote by Prof. Wurzer at Nordex about IP-designKeynote by Prof. Wurzer at Nordex about IP-design
Keynote by Prof. Wurzer at Nordex about IP-designMIPLM
 
Choosing the Right CBSE School A Comprehensive Guide for Parents
Choosing the Right CBSE School A Comprehensive Guide for ParentsChoosing the Right CBSE School A Comprehensive Guide for Parents
Choosing the Right CBSE School A Comprehensive Guide for Parentsnavabharathschool99
 
ACC 2024 Chronicles. Cardiology. Exam.pdf
ACC 2024 Chronicles. Cardiology. Exam.pdfACC 2024 Chronicles. Cardiology. Exam.pdf
ACC 2024 Chronicles. Cardiology. Exam.pdfSpandanaRallapalli
 
AMERICAN LANGUAGE HUB_Level2_Student'sBook_Answerkey.pdf
AMERICAN LANGUAGE HUB_Level2_Student'sBook_Answerkey.pdfAMERICAN LANGUAGE HUB_Level2_Student'sBook_Answerkey.pdf
AMERICAN LANGUAGE HUB_Level2_Student'sBook_Answerkey.pdfphamnguyenenglishnb
 
ISYU TUNGKOL SA SEKSWLADIDA (ISSUE ABOUT SEXUALITY
ISYU TUNGKOL SA SEKSWLADIDA (ISSUE ABOUT SEXUALITYISYU TUNGKOL SA SEKSWLADIDA (ISSUE ABOUT SEXUALITY
ISYU TUNGKOL SA SEKSWLADIDA (ISSUE ABOUT SEXUALITYKayeClaireEstoconing
 
4.16.24 21st Century Movements for Black Lives.pptx
4.16.24 21st Century Movements for Black Lives.pptx4.16.24 21st Century Movements for Black Lives.pptx
4.16.24 21st Century Movements for Black Lives.pptxmary850239
 
What is Model Inheritance in Odoo 17 ERP
What is Model Inheritance in Odoo 17 ERPWhat is Model Inheritance in Odoo 17 ERP
What is Model Inheritance in Odoo 17 ERPCeline George
 
Field Attribute Index Feature in Odoo 17
Field Attribute Index Feature in Odoo 17Field Attribute Index Feature in Odoo 17
Field Attribute Index Feature in Odoo 17Celine George
 
Earth Day Presentation wow hello nice great
Earth Day Presentation wow hello nice greatEarth Day Presentation wow hello nice great
Earth Day Presentation wow hello nice greatYousafMalik24
 
Transaction Management in Database Management System
Transaction Management in Database Management SystemTransaction Management in Database Management System
Transaction Management in Database Management SystemChristalin Nelson
 
4.18.24 Movement Legacies, Reflection, and Review.pptx
4.18.24 Movement Legacies, Reflection, and Review.pptx4.18.24 Movement Legacies, Reflection, and Review.pptx
4.18.24 Movement Legacies, Reflection, and Review.pptxmary850239
 
call girls in Kamla Market (DELHI) 🔝 >༒9953330565🔝 genuine Escort Service 🔝✔️✔️
call girls in Kamla Market (DELHI) 🔝 >༒9953330565🔝 genuine Escort Service 🔝✔️✔️call girls in Kamla Market (DELHI) 🔝 >༒9953330565🔝 genuine Escort Service 🔝✔️✔️
call girls in Kamla Market (DELHI) 🔝 >༒9953330565🔝 genuine Escort Service 🔝✔️✔️9953056974 Low Rate Call Girls In Saket, Delhi NCR
 
THEORIES OF ORGANIZATION-PUBLIC ADMINISTRATION
THEORIES OF ORGANIZATION-PUBLIC ADMINISTRATIONTHEORIES OF ORGANIZATION-PUBLIC ADMINISTRATION
THEORIES OF ORGANIZATION-PUBLIC ADMINISTRATIONHumphrey A Beña
 
Difference Between Search & Browse Methods in Odoo 17
Difference Between Search & Browse Methods in Odoo 17Difference Between Search & Browse Methods in Odoo 17
Difference Between Search & Browse Methods in Odoo 17Celine George
 

Kürzlich hochgeladen (20)

Judging the Relevance and worth of ideas part 2.pptx
Judging the Relevance  and worth of ideas part 2.pptxJudging the Relevance  and worth of ideas part 2.pptx
Judging the Relevance and worth of ideas part 2.pptx
 
ECONOMIC CONTEXT - PAPER 1 Q3: NEWSPAPERS.pptx
ECONOMIC CONTEXT - PAPER 1 Q3: NEWSPAPERS.pptxECONOMIC CONTEXT - PAPER 1 Q3: NEWSPAPERS.pptx
ECONOMIC CONTEXT - PAPER 1 Q3: NEWSPAPERS.pptx
 
How to do quick user assign in kanban in Odoo 17 ERP
How to do quick user assign in kanban in Odoo 17 ERPHow to do quick user assign in kanban in Odoo 17 ERP
How to do quick user assign in kanban in Odoo 17 ERP
 
USPS® Forced Meter Migration - How to Know if Your Postage Meter Will Soon be...
USPS® Forced Meter Migration - How to Know if Your Postage Meter Will Soon be...USPS® Forced Meter Migration - How to Know if Your Postage Meter Will Soon be...
USPS® Forced Meter Migration - How to Know if Your Postage Meter Will Soon be...
 
Incoming and Outgoing Shipments in 3 STEPS Using Odoo 17
Incoming and Outgoing Shipments in 3 STEPS Using Odoo 17Incoming and Outgoing Shipments in 3 STEPS Using Odoo 17
Incoming and Outgoing Shipments in 3 STEPS Using Odoo 17
 
Keynote by Prof. Wurzer at Nordex about IP-design
Keynote by Prof. Wurzer at Nordex about IP-designKeynote by Prof. Wurzer at Nordex about IP-design
Keynote by Prof. Wurzer at Nordex about IP-design
 
Choosing the Right CBSE School A Comprehensive Guide for Parents
Choosing the Right CBSE School A Comprehensive Guide for ParentsChoosing the Right CBSE School A Comprehensive Guide for Parents
Choosing the Right CBSE School A Comprehensive Guide for Parents
 
ACC 2024 Chronicles. Cardiology. Exam.pdf
ACC 2024 Chronicles. Cardiology. Exam.pdfACC 2024 Chronicles. Cardiology. Exam.pdf
ACC 2024 Chronicles. Cardiology. Exam.pdf
 
AMERICAN LANGUAGE HUB_Level2_Student'sBook_Answerkey.pdf
AMERICAN LANGUAGE HUB_Level2_Student'sBook_Answerkey.pdfAMERICAN LANGUAGE HUB_Level2_Student'sBook_Answerkey.pdf
AMERICAN LANGUAGE HUB_Level2_Student'sBook_Answerkey.pdf
 
ISYU TUNGKOL SA SEKSWLADIDA (ISSUE ABOUT SEXUALITY
ISYU TUNGKOL SA SEKSWLADIDA (ISSUE ABOUT SEXUALITYISYU TUNGKOL SA SEKSWLADIDA (ISSUE ABOUT SEXUALITY
ISYU TUNGKOL SA SEKSWLADIDA (ISSUE ABOUT SEXUALITY
 
Model Call Girl in Tilak Nagar Delhi reach out to us at 🔝9953056974🔝
Model Call Girl in Tilak Nagar Delhi reach out to us at 🔝9953056974🔝Model Call Girl in Tilak Nagar Delhi reach out to us at 🔝9953056974🔝
Model Call Girl in Tilak Nagar Delhi reach out to us at 🔝9953056974🔝
 
4.16.24 21st Century Movements for Black Lives.pptx
4.16.24 21st Century Movements for Black Lives.pptx4.16.24 21st Century Movements for Black Lives.pptx
4.16.24 21st Century Movements for Black Lives.pptx
 
What is Model Inheritance in Odoo 17 ERP
What is Model Inheritance in Odoo 17 ERPWhat is Model Inheritance in Odoo 17 ERP
What is Model Inheritance in Odoo 17 ERP
 
Field Attribute Index Feature in Odoo 17
Field Attribute Index Feature in Odoo 17Field Attribute Index Feature in Odoo 17
Field Attribute Index Feature in Odoo 17
 
Earth Day Presentation wow hello nice great
Earth Day Presentation wow hello nice greatEarth Day Presentation wow hello nice great
Earth Day Presentation wow hello nice great
 
Transaction Management in Database Management System
Transaction Management in Database Management SystemTransaction Management in Database Management System
Transaction Management in Database Management System
 
4.18.24 Movement Legacies, Reflection, and Review.pptx
4.18.24 Movement Legacies, Reflection, and Review.pptx4.18.24 Movement Legacies, Reflection, and Review.pptx
4.18.24 Movement Legacies, Reflection, and Review.pptx
 
call girls in Kamla Market (DELHI) 🔝 >༒9953330565🔝 genuine Escort Service 🔝✔️✔️
call girls in Kamla Market (DELHI) 🔝 >༒9953330565🔝 genuine Escort Service 🔝✔️✔️call girls in Kamla Market (DELHI) 🔝 >༒9953330565🔝 genuine Escort Service 🔝✔️✔️
call girls in Kamla Market (DELHI) 🔝 >༒9953330565🔝 genuine Escort Service 🔝✔️✔️
 
THEORIES OF ORGANIZATION-PUBLIC ADMINISTRATION
THEORIES OF ORGANIZATION-PUBLIC ADMINISTRATIONTHEORIES OF ORGANIZATION-PUBLIC ADMINISTRATION
THEORIES OF ORGANIZATION-PUBLIC ADMINISTRATION
 
Difference Between Search & Browse Methods in Odoo 17
Difference Between Search & Browse Methods in Odoo 17Difference Between Search & Browse Methods in Odoo 17
Difference Between Search & Browse Methods in Odoo 17
 

Java Persistence API

  • 1. Java Persistence API Ilio Catallo - info@iliocatallo.it
  • 2. Outline • Object vs. rela/onal model • En//es and EntityManager • Integra/ng JPA into Spring • Mapping rela/onships • Querying the data source • References
  • 4. Object vs. rela.onal model The end-point of every Web applica5on is the DBMS
  • 5. Object vs. rela.onal model In many cases, the DBMS has been around for much longer than the Web applica;on
  • 6. Object vs. rela.onal model It is up to the object model of the Web app to find ways to work with the database schema
  • 7. Object vs. rela.onal model The technique of bridging the gap between the object model and the rela7onal model is known as object-rela+onal mapping (ORM)
  • 8. Object vs. rela.onal model Object-rela+onal mapping techniques try to map the concepts from one model onto another
  • 9. Impedance mismatch ┌───────────────────────────────┬──────────────────────────────┐ │////////// OOP Model //////////│////// Relational model /////│ ├───────────────────────────────┼──────────────────────────────┤ │ Classes, objects │ Tables, rows │ ├───────────────────────────────┼──────────────────────────────┤ │ Attributes, properties │ Columns │ ├───────────────────────────────┼──────────────────────────────┤ │ Identity │ Primary key │ ├───────────────────────────────┼──────────────────────────────┤ │ References to other entities │ Foreign key │ ├───────────────────────────────┼──────────────────────────────┤ │ Inheritance, polymorphism │ Not supported │ ├───────────────────────────────┼──────────────────────────────┤ │ Methods │ Stored procedures, triggers │ ├───────────────────────────────┼──────────────────────────────┤ │ Code is portable │ Code is vendor-depending │ └───────────────────────────────┴──────────────────────────────┘
  • 10. The challenge of mapping one model to the other lies in the concepts in each for which there is no logical equivalent in the other
  • 11. Impedance mismatch As a result, moving data back and forth between a DBMS and the object model is a lot harder than it needs to be
  • 12. Impedance mismatch Java developers find themselves spending effort in wri5ng lots of code to convert rows and columns into objects
  • 14. The problem with JDBC JDBC has been the first major support for database persistence
  • 15. The problem with JDBC JDBC offers an abstrac'on of the proprietary client programming interfaces provided by database vendors
  • 16. The problem with JDBC Although JDBC is portable, the SQL language is not
  • 17. The problem with JDBC It is rare to write SQL of any complexity that runs unchanged on two major database pla:orms
  • 18. Java Persistence API The Java Persistence API (JPA) bridges the gap between object- oriented domain models and rela:onal database systems
  • 19. Java Persistence API JPA 2.1 was developed by the JSR-338 so:ware expert group
  • 20. Java Persistence API Despite its ini)al associa)on with EJBs, JPA is a JSE API, as reflected by its belonging to the java.persistence package
  • 21. Java Persistence API JPA provides an ease-of-use abstrac5on on top of JDBC ┌──────────────────┐ ┌──────────────────┐ │ Java │ │ Vendor- │ │ Persistence API │ │ specific API │ └──────────────────┘ └──────────────────┘ ┌───────────────────────────────────────┐ │ │ The persistence provider │ Persistence provider │ is in charge of the ORM │ │ └───────────────────────────────────────┘ ┌───────────────────────────────────────┐ │ │ JDBC provides methods │ JDBC │ for querying and updating │ │ data in the database └───────────────────────────────────────┘ ┌───────────────────────────────────────┐ │ │ │ DBMS │ │ │ └───────────────────────────────────────┘
  • 22. Java Persistence API The code can therefore be isolated from vendor-specific peculiari1es and rela1on model peculiari1es ┌──────────────────┐ ┌──────────────────┐ │ Java │ │ Vendor- │ │ Persistence API │ │ specific API │ └──────────────────┘ └──────────────────┘ ┌───────────────────────────────────────┐ │ │ The persistence provider │ Persistence provider │ is in charge of the ORM │ │ └───────────────────────────────────────┘ ┌───────────────────────────────────────┐ │ │ JDBC provides methods │ JDBC │ for querying and updating │ │ data in the database └───────────────────────────────────────┘ ┌───────────────────────────────────────┐ │ │ │ DBMS │ │ │ └───────────────────────────────────────┘
  • 23. JPA main features • POJO persistence • Non-intrusiveness • Object queries
  • 24. POJO persistence JPA provides a Plain Old Java Object (POJO) persistence model public class Employee { private int id; private String name; private long salary; public Employee() {...} // other methods (e.g., getters and setters) }
  • 25. POJO persistence There is nothing special about the objects being persisted public class Employee { private int id; private String name; private long salary; public Employee() {...} // other methods (e.g., getters and setters) }
  • 26. POJO persistence Any exis)ng non-final class with a default constructor can be made persistable public class Employee { private int id; private String name; private long salary; public Employee() {...} // other methods (e.g., getters and setters) }
  • 27. Non-intrusiveness The persistence API exists as a separate layer from the domain model ┌──────┐┌────────────────────────────────┐ │ D ││ │ │ o ││ Presentation layer │ │ m ││ │ │ a │└────────────────────────────────┘ │ i │┌────────────────────────────────┐ │ n ││ │ │ ││ Service layer │ │ m ││ │ │ o │└────────────────────────────────┘ │ d │┌────────────────────────────────┐ │ e ││ │ │ l ││ Persistence layer │ │ ││ │ └──────┘└────────────────────────────────┘
  • 28. Non-intrusiveness That is, the persisted objects are not aware of the persistence layer ┌──────┐┌────────────────────────────────┐ │ D ││ │ │ o ││ Presentation layer │ │ m ││ │ │ a │└────────────────────────────────┘ │ i │┌────────────────────────────────┐ │ n ││ │ │ ││ Service layer │ │ m ││ │ │ o │└────────────────────────────────┘ │ d │┌────────────────────────────────┐ │ e ││ │ │ l ││ Persistence layer │ │ ││ │ └──────┘└────────────────────────────────┘
  • 29. Object queries JPA comes with an object-oriented query language that operates on classes and objects, rather than tables and rows SELECT c FROM Category c WHERE c.items is NOT EMPTY
  • 31. En##es in the rela#onal paradigm In the rela*onal paradigm, an en#ty is something that can be recognized to have a7ributes and rela*onships id departOn ● ○ │ │ ┌───┴───────────┴─────┐ │ │ arriveOn │ Flight │─────○ │ │ └─────────────────────┘
  • 32. En##es in the rela#onal paradigm An en%ty has an independent existence and can be uniquely iden/fied id departOn ● ○ │ │ ┌───┴───────────┴─────┐ │ │ arriveOn │ Flight │─────○ │ │ └─────────────────────┘
  • 33. En##es in the rela#onal paradigm An en%ty may par$cipate in rela$onships with any number of other en%%es in a number of standard ways +---------+ +---------+ +----------+ | | | | | | | +-----> +------> | | | | | | | +---------+ +---------+ +----------+ Flight FlightLeg Airport
  • 34. En##es in the OO paradigm In the object-oriented paradigm, we would add behavior to an en7ty and call it a class public class Flight { private List<FlightLeg> legs; private BigDecimal totalCost; public Flight(...) {...} public boolean isNonStop() {...} public long getTotalTravelTime() {...} // other methods }
  • 35. The intui)on behind ORM Hence, the intui%on behind object-rela2onal mapping is that • Classes correspond to tables • Objects correspond to tuples
  • 36. En#ty classes The @Entity annota)on is used to qualify a class as an en'ty @Entity public class Employee { @Id private int id; private String name; private long salary; public Employee() { ... } // other methods (e.g., getters and setters) }
  • 37. En#ty classes En#ty objects are just plain-old Java objects Employee emp1 = new Employee(12, "Jon Snow"); Employee emp2 = new Employee(20, "Portgas D. Ace");
  • 38. En#ty requirements En##es must respect some requirements • The en'ty class must have a public or protected default constructor • The en'ty class must not be final
  • 39. En#ty requirements En##es must respect some requirements • No method or variables of the en3ty class may be final • If an en3ty object is to be passed as a detached object, the Serializable interface must be implemented
  • 40. Persistence unit We refer to the set of en(ty classes as the persistence unit @Entity public class Employee { ... } @Entity public class Department { ... } @Entity public class ParkingSpace { ... }
  • 41. EntityManager EntityManager is the central authority for all persistence ac/ons
  • 42. EntityManager EntityManager provides methods for crea0ng queries, finding objects, synchronizing, and inser0ng objects into the DB
  • 43. EntityManager The EntityManager API directly maps to CRUD opera8ons • persist (INSERT) • merge (UPDATE) • remove (DELETE) • find (SELECT)
  • 44. Crea%ng a new en%ty En#ty objects do not become persistent just by invoking the new operator1 Employee e = new Employee(12, "Jon Snow”) 1 How would they auto-magically become persistent? A:er all, we said that en<<es objects are just POJOs
  • 45. Crea%ng a new en%ty Newly-created objects are in the transient state, since the EntityManager does not know they exist yet Employee e = new Employee(12, "Jon Snow")
  • 46. Persis&ng an en&ty En#ty objects remain transient un#l we no#fy the EntityManager of their existence Employee e = new Employee(12, "Jon Snow")
  • 47. Persis&ng an en&ty The persist() method no#fies the En+tyManager of the existence of a given transient en+ty object2 Employee emp = new Employee(12, "Jon Snow"); entityManager.persist(emp); 2 Remembr that the persist() method does not actually cause the en3ty object to be immediately persisted, we are just sending a no3fica3on to the EntityManager
  • 48. Persis&ng an en&ty The en&ty object enters the managed state Employee emp = new Employee(12, "Jon Snow"); entityManager.persist(emp);
  • 49. Persis&ng an en&ty EntityManager makes sure that each managed object is synchronized with the related database tuple Employee emp = new Employee(12, "Jon Snow"); entityManager.persist(emp);
  • 50. Persistence context The set of managed objects is called the persistence context ┌─────────────────────────────┐ │ │ │ ● o1 │ ● o5 │ │ │ ● o4 │ ● o6 │ │ │ ● o2 │ │ ● o3 │ ● o7 │ │ └─────────────────────────────┘ Persistence context
  • 51. Persistence context EntityManger is the persistence context supervisor, whose responsibility is to keep in sync managed objects with tuples EntityManager ◊ │ ┌──────────────────┼──────────┐ │ │ │ │ │ │ │ ● o1 │ ● o5 │ │ │ ● o4 │ ● o6 │ │ │ ● o2 │ │ ● o3 │ ● o7 │ │ └─────────────────────────────┘ Persistence context
  • 52. Persistence context Each EntityManager has its own persistence context, and there may exist several EntityManagers at once EntityManager A EntityManager B ◊ ◊ │ │ ┌──────────────────┼──────────┐ ┌──────────────────┼──────────┐ │ │ │ │ │ │ │ │ │ │ │ │ │ ● o1 │ │ ● o5 │ ● o9 │ │ │ │ │ ● o4 │ │ ● o7 │ ● o8 │ │ │ │ │ ● o2 │ │ ● o6 │ │ ● o3 │ │ │ ● o10 │ │ │ │ └─────────────────────────────┘ └─────────────────────────────┘ Persistence context A Persistence context B
  • 53. Finding an en)ty The find() method finds en*ty objects by primary key Employee emp = entityManager.find(Employee.class, 12);
  • 54. Finding an en)ty When the call completes, the returned en2ty object is in the managed state Employee emp = entityManager.find(Employee.class, 12);
  • 55. Finding an en)ty The find() method returns null if the en/ty cannot be found Employee emp = entityManager.find(Employee.class, 12);
  • 56. Removing an en+ty The remove() method removes the data associated with an en/ty object from the database entityManager.remove(emp);
  • 57. Removing an en+ty The remove() method will also detach the en/ty object entityManager.remove(emp);
  • 58. Removing an en+ty Once detached, an en+ty is no longer managed by the related EntityManager, i.e., it is no longer part of its persistence context entityManager.remove(emp);
  • 59. Removing an en+ty Since the related tuple is deleted, the en1ty objects enters the removed state entityManager.remove(emp);
  • 60. Removing an en+ty Removed en))es cannot be made managed again entityManager.remove(emp);
  • 61. En#ty’s lifecycle +-------------+ | | | Persisted | | | +------+------+ | | find()/ | query | +-------------+ +------v-------+ +-----------+ new | | persist() | | remove() | | +----------> Transient +-------------> Managed +------------> Removed | | | | | | | +-------------+ +---+------^---+ +-----------+ | | out of scope/ | | merge()/ serialized/ | | refresh() cloned | | | | +---v------+---+ | | | Detached | | | +--------------+
  • 62. Iden%fier genera%on Some%mes, applica%ons do not want to explicitly manage uniqueness in some aspect of their domain model
  • 63. Iden%fier genera%on The persistence provider can automa&cally generate an iden0fier for every en0ty object of a given type
  • 64. Iden%fier genera%on This persistence provider’s feature is called iden%fier genera%on and is specified by the @GeneratedValue annota7on @Entity public class Employee {     @Id @GeneratedValue     private int id;     ... }
  • 65. Iden%fier genera%on Applica'ons can choose one out of four genera*on strategies ┌──────────────────────────────┬─────────────────────────────────────────┐ │/// Id generation strategy ///│////////////// Description /////////////│ ├──────────────────────────────┼─────────────────────────────────────────┤ │ │The provider generates identifiers by │ │ AUTO │using whatever strategy it wants │ │ │ │ ├──────────────────────────────┼─────────────────────────────────────────┤ │ │Identifiers are generated according to a │ │ TABLE │generator table │ │ │ │ ├──────────────────────────────┼─────────────────────────────────────────┤ │ │If the underlying DB supports sequences, │ │ SEQUENCE │the provider will use this feature for │ │ │generating ids │ ├──────────────────────────────┼─────────────────────────────────────────┤ │ │If the underlying DB supports primary key│ │ IDENTITY │identity columns, the provider will use │ │ │this feature for generating ids │ └──────────────────────────────┴─────────────────────────────────────────┘
  • 66. AUTO strategy Remember that the AUTO mode is a genera0on strategy mainly meant for developing prototypes @Entity public class Employee {     @Id @GeneratedValue(strategy=GenerationType.AUTO)     private int id;     ... }
  • 67. AUTO strategy In any other situa.on, it would be be4er to use other genera.on strategies @Entity public class Employee {     @Id @GeneratedValue(strategy=GenerationType.AUTO)     private int id;     ... }
  • 69. Required steps To use JPA in our Spring Web applica5on we need to 1. Define a data source 2. Understand how to produce EntityManager instances 3. Introduce transac8onal seman8cs into the service layer 4. Write JPA-based repository beans
  • 70. 1. Defining a data source
  • 71. Data source Regardless of the persistence framework, we need to configure a reference to a data source
  • 72. Pooled data source When developing mul/threading applica/ons, the common recommenda/on is to use a pooled data source
  • 73. Pooled data source A pooled data source is a data source that draws its connec2ons from a connec%on pool
  • 74. Pooled data source Unfortunately, Spring does not provide a na5ve pooled data source
  • 75. Pooled data source We will use the pooled data source coming from the Apache Database Connec/on Pooling (DBCP) project
  • 76. Declaring the data source By altering dataSource-context.xml, we can declare the new data source as a bean in the back-end container <bean id="dataSource" class="org.apache.commons.dbcp2.BasicDataSource"> <property name="driverClassName" value="com.mysql.jdbc.Driver"/> <property name="url" value="jdbc:mysql://server:3306/db_schema"/> <property name="username" value=”dbuser"/> <property name="password" value=”dbpassword"/> </bean>
  • 77. Declaring the data source BasicDataSource is the class implemen-ng the pooled data source <bean id="dataSource" class="org.apache.commons.dbcp2.BasicDataSource"> <property name="driverClassName" value="com.mysql.jdbc.Driver"/> <property name="url" value="jdbc:mysql://server:3306/db_schema"/> <property name="username" value=”dbuser"/> <property name="password" value=”dbpassword"/> </bean>
  • 78. Declaring the data source com.mysql.jdbc.Driver is the class implemen-ng the JDBC driver <bean id="dataSource" class="org.apache.commons.dbcp2.BasicDataSource"> <property name="driverClassName" value="com.mysql.jdbc.Driver"/> <property name="url" value="jdbc:mysql://server:3306/db_schema"/> <property name="username" value=”dbuser"/> <property name="password" value=”dbpassword"/> </bean>
  • 79. Maven dependencies As usual, we can use Maven to automa1cally resolve dependencies <dependency> <groupId>org.apache.commons</groupId> <artifactId>commons-dbcp2</artifactId> <version>2.1.1</version> </dependency>
  • 80. Maven dependencies As usual, we can use Maven to automa1cally resolve dependencies <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>5.1.38</version> </dependency>
  • 81. 2. Obtaining an EntityManager
  • 82. Obtaining an EntityManager Although we discussed the role of EntityManager, we s2ll do not know how to obtain an EntityManager instance
  • 83. Obtaining an EntityManager The JPA specifica.on defines two kinds of EntityManagers • Applica(on-managed • Container-managed
  • 84. Applica'on-managed Applica'on-managed EntityManagers are created by the applica.on itself EntityManagerFactory emf = Persistence.createEntityManagerFactory("MyPersistenceUnit"); EntityManager em = emf.createEntityManager();
  • 85. Applica'on-managed The applica*on is responsible for every aspect of the EntityManager’s lifecycle EntityManager em = emf.createEntityManager(); ... entityManager.close();
  • 86. Applica'on-managed The applica*on also needs to manually manage transac'ons entityManager.getTransaction().begin(); entityManager.getTransaction().commit();
  • 87. Applica'on-managed This kind of EntityManager is typical of JSE applica*ons
  • 88. Container-managed Container-managed EntityManagers are created by a container, which also injects them into the applica5on components
  • 89. EntityManager beans Spring supports both types of EntityManager instances
  • 90. EntityManager beans • LocalEntityManagerFactoryBean for applica+on-managed EntityManagers • LocalContainerEntityManagerFactoryBean for container-managed EntityManagers3 3 Actually, LocalEntityManagerFactoryBean (resp. LocalContainerEntityManagerFactoryBean) produces applica5on-managed (resp. container-managed) EntityManagerFactorys, which will in turn produce applica5on-managed (resp. container-managed) EntityManagers
  • 91. EntityManager beans The following declares a factory bean for container-managed EntityManagers in dataSource-context.xml <bean id="emf" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean"> <property name="dataSource" ref="dataSource"/> <property name="packagesToScan" value="it.polimi.awt.springmvc.domain"/> <property name="persistenceUnitName" value=”MyPersistenceUnit"/> ... </bean>
  • 92. EntityManager beans dataSource is the data source bean we previously declared <bean id="emf" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean"> <property name="dataSource" ref="dataSource"/> <property name="packagesToScan" value="it.polimi.awt.springmvc.domain"/> <property name="persistenceUnitName" value=”MyPersistenceUnit"/> ... </bean>
  • 93. EntityManager beans it.polimi.awt.springmvc.domain is the package containing the classes to be persisted <bean id="emf" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean"> <property name="dataSource" ref="dataSource"/> <property name="packagesToScan" value="it.polimi.awt.springmvc.domain"/> <property name="persistenceUnitName" value=”MyPersistenceUnit"/> ... </bean>
  • 94. EntityManager beans MyPersistenceUnit is the name of the persistence unit <bean id="emf" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean"> <property name="dataSource" ref="dataSource"/> <property name="packagesToScan" value="it.polimi.awt.springmvc.domain"/> <property name="persistenceUnitName" value=”MyPersistenceUnit"/> </bean>
  • 95. Persistence provider Several possible JPA implementa3ons can be used as the persistence provider • EclipseLink • Hibernate • OpenJPA • TopLink
  • 96. Persistence provider One way to tell Spring which implementa3on to use is to declare a JpaVendorAdapter bean in dataSource-context.xml <bean id="jpaVendorAdapter" class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter"> <property name="database" value="MYSQL"/> </bean>
  • 97. Persistence provider Specifically, we use HibernateJpaVendorAdapter to denote that Hibernate is our persistence provider <bean id="jpaVendorAdapter" class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter"> <property name="database" value="MYSQL"/> </bean>
  • 98. Persistence provider We set the database property to MYSQL to denote that MySQL is the underlying RDBMS <bean id="jpaVendorAdapter" class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter"> <property name="database" value="MYSQL"/> </bean>
  • 99. Persistence provider We can now set-inject our JpaVendorAdapter bean into the LocalContainerEntityManagerFactoryBean: <bean id="emf" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean"> <property name="dataSource" ref="dataSource"/> <property name="packagesToScan" value="it.polimi.awt.springmvc.domain"/> <property name="persistenceUnitName" value=”MyPersistenceUnit"/> <property name="jpaVendorAdapter" ref="jpaVendorAdapter"/> </bean>
  • 101. Alterna(ves exist No#ce we managed to integrate JPA in Spring by solely adding beans into the back-end container
  • 102. persistence.xml That is, we did not have to introduce the standard JPA deployment descriptor file persistence.xml
  • 103. persistence.xml <persistence> <persistence-unit name="MyPersistenceUnit"> <provider>org.hibernate.ejb.HibernatePersistence</provider> <properties> <property name="javax.persistence.jdbc.driver" value="com.mysql.jdbc.Driver"/> <property name="javax.persistence.jdbc.url" value="jdbc:mysql://serverurl:3306/db-schema"/> <property name="javax.persistence.jdbc.user" value="dbuser"/> <property name="javax.persistence.jdbc.password" value="dbpasswd"/> </properties> </persistence-unit> </persistence>
  • 104. 3. Dealing with transac1ons
  • 105. Transac'ons In so&ware, all-or-nothing opera3ons are called transac'ons Everything goes well +-------------------> +-----------------------+ | | | | | 1. Verify seats | | Purchase ticket | 2. Reserve seat | | +-----------------------> 3. Receive payment +----+ | 4. Issue ticket | | | | | +-----------------------+ | +--------------------> Something goes wrong
  • 106. Transac'ons Transac'ons allow grouping several opera'ons into a single unit of work that either fully happens or fully does not happen Everything goes well +-------------------> +-----------------------+ | | | | | 1. Verify seats | | Purchase ticket | 2. Reserve seat | | +-----------------------> 3. Receive payment +----+ | 4. Issue ticket | | | | | +-----------------------+ | +--------------------> Something goes wrong
  • 107. Transac'onal boundary The service layer is the transac'onal boundary of the applica1on ┌──────┐┌────────────────────────────────┐ │ D ││ │ │ o ││ Presentation layer │ │ m ││ │ │ a │└────────────────────────────────┘ │ i │╔════════════════════════════════╗ │ n │║ ║ │ │║ Service layer ║ │ m │║ ║ │ o │╚════════════════════════════════╝ │ d │┌────────────────────────────────┐ │ e ││ │ │ l ││ Persistence layer │ │ ││ │ └──────┘└────────────────────────────────┘
  • 108. Transac'onal boundary If a service method makes mul3ple calls against one or more persistence beans, we want those calls to operate as part of a single transac,on
  • 109. Transac'onal boundary To handle this, the service layer needs a way to embed its persistence calls within the context of a transac,on
  • 110. Transac'onal boundary Transaction | +-----------------------------------------------|-------------------------------------------------+ | | | | | | | +-----------------v-----------------+ | | | | | | | AccountService.transferFunds() | | | | | | | +-----------------+-----------------+ | | | | | | | | | | | | | | +---------------------------------------------------------------+ | | | | | | | | | | | | +------------v-----------+ +-----------v------------+ +-----------v-----------+ | | | | | | | | | | | AccountRepository | | AccountRepository | | LogRepository | | | | .update(account1) | | .update(account2) | | .create(entry) | | | | | | | | | | | +------------------------+ +------------------------+ +-----------------------+ | | | | | +-------------------------------------------------------------------------------------------------+
  • 111. Transac'on managers Spring does not directly manage transac1ons
  • 112. Transac'on managers Instead, it provides a selec1on of transac'on managers • JpaTransactionManager • JtaTransactionManager • JdoTransactionManager
  • 113. Transac'on managers Each such transac+on manager acts as a façade to a pla2orm- specific implementa+on • JpaTransactionManager • JtaTransactionManager • JdoTransactionManager
  • 114. Declaring a transac-on manager The transac+on manager of interest needs to be declared in dataSource-context.xml <bean id=”transactionManager” class="org.springframework.orm.jpa.JpaTransactionManager"> <property name="entityManagerFactory" ref="emf"/> </bean>
  • 115. Declaring a transac-on manager JpaTransactionManager needs to be wired to a EntityManagerFactory <bean id=”transactionManager” class="org.springframework.orm.jpa.JpaTransactionManager"> <property name="entityManagerFactory" ref="emf"/> </bean>
  • 116. Declaring a transac-on manager JpaTransactionManager collaborates with the EntityManager that is produced by the factory to conduct transac4ons <bean id=”transactionManager” class="org.springframework.orm.jpa.JpaTransactionManager"> <property name="entityManagerFactory" ref="emf"/> </bean>
  • 117. Two types of transac/ons Spring provides two ways of specifying transac3ons • Programma(c transac(ons • Declara(ve transac(ons
  • 118. Declara've transac'ons Most Spring users choose declara've transac'on management, as this op2on has the least impact on applica2on code
  • 119. Declara've transac'ons Declara've transac'ons allow keeping business code free from repe$$ve transac$on demarca$on code public void saveAccount(Account account) { txTemplate.execute(new TransactionCallback<Void>() { public void doInTransaction(TransactionStatus txStatus) { try { repository.saveAccount(account); } catch (RuntimeException e) { txStatus.setRollbackOnly(); throw e; } } }); }
  • 120. @Transactional The @Transactional annota)on specifies that an interface, class, or method must have transac'onal seman'cs @Service @Transactional public class AccountServiceImpl implements AccountService { ... }
  • 121. @Transactional From this point on, opera/ons will be transac'onal @Service @Transactional public class AccountServiceImpl implements AccountService { ... }
  • 122. @Transactional When needed, addi$onal transac-onal seman$cs can be specified (e.g., marking the transac-ons as read-only) @Service @Transactional(readOnly = true) public class AccountServiceImpl implements AccountService { ... }
  • 123. Ac#vate declara#ve transac#ons A simple addi+on to dataSource-context.xml allows ac+va+ng declara+ve transac+ons <tx:annotation-driven/>
  • 124. Maven dependencies As usual, we can use Maven to automa1cally resolve dependencies <dependency> <groupId>org.springframework</groupId> <artifactId>spring-tx</artifactId> <version>4.2.5.RELEASE</version> </dependency>
  • 125. 4. How to write JPA repository beans
  • 126. Persistence context Let us intend the persistence context as a cache
  • 127. Persistence context The objects we alter could then be intended as a in-memory copy of the data in the database
  • 128. Persistence context Hence, by doing account.getBalance() we access the in- memory object rather than taking the data from the database
  • 129. Persistence context Similarly, by doing account.setBalance(5000) we alter the in-memory object, rather than the data on the database
  • 130. Persistence context At a certain point the persistence context needs to be flushed so as to mirror the changes in the database
  • 131. Within the same transac-on, how many persistence contexts should exist?
  • 132. One persistence context In any given transac.on, we want exactly one persistence context (i.e., cache) for a given set of data Transaction | +-----------------------------------------------|-------------------------------------------------+ | | | | | | | +-----------------v-----------------+ | | | | | | | AccountService.transferFunds() | | | | | | | +-----------------+-----------------+ | | | | | | | | | | | | | | +---------------------------------------------------------------+ | | | | | | | | | | | | +------------v-----------+ +-----------v------------+ +-----------v-----------+ | | | | | | | | | | | AccountRepository | | AccountRepository | | LogRepository | | | | .update(account1) | | .update(account2) | | .create(entry) | | | | | | | | | | | +------------------------+ +------------------------+ +-----------------------+ | | | | | +-------------------------------------------------------------------------------------------------+
  • 133. One persistence context By doing so, the different calls comprised in the transac3on will interact with the same data Transaction | +-----------------------------------------------|-------------------------------------------------+ | | | | | | | +-----------------v-----------------+ | | | | | | | AccountService.transferFunds() | | | | | | | +-----------------+-----------------+ | | | | | | | | | | | | | | +---------------------------------------------------------------+ | | | | | | | | | | | | +------------v-----------+ +-----------v------------+ +-----------v-----------+ | | | | | | | | | | | AccountRepository | | AccountRepository | | LogRepository | | | | .update(account1) | | .update(account2) | | .create(entry) | | | | | | | | | | | +------------------------+ +------------------------+ +-----------------------+ | | | | | +-------------------------------------------------------------------------------------------------+
  • 134. One persistence context Therefore, we want exactly one EntityManger per transac3on, as different EntitManagers correspond to different persistence contexts
  • 135. Persistence context propaga/on We want to automa&cally propagate the same persistence context to all the beans involved in the same transac5on @Repository public class AccountRepositoryImpl implements AccountRepository {...} @Repository public class LogRepositoryImpl implements LogRepository {...}
  • 136. Persistence context propaga/on This amounts to injec/ng the same EntityManager to all the components involved @Repository public class JpaAccountRepository implements AccountRepository {...} @Repository public class JpaLogRepository implements LogRepository {...}
  • 137. @PersistenceContext The @PersistenceContext annota)on automa&cally propagates the persistence context @Repository public class JpaAccountRepository implements AccountRepository { @PersistenceContext private EntityManager em; @Override public Account findById(int id) { return em.find(Account.class, id); } }
  • 139. En##es and rela#onships If en&&es were isolated from one another, the issue of ORM would be a trivial one +------------+ +--------------+ | | | | | Employee | | Department | | | | | +------------+ +--------------+
  • 140. En##es and rela#onships In reality, most en//es need to be able to have rela%onships with other en//es +------------+ +--------------+ | | | | | Employee +-------------> Department | | | * 1 | | +------------+ +--------------+
  • 141. En##es and rela#onships This is what produces the domain model of the applica2on +------------+ +--------------+ | | | | | Employee +-------------> Department | | | * 1 | | +------------+ +--------------+
  • 142. Rela%onships Every rela)onship has four characteris-cs • Direc'onality • Role • Cardinality • Ownership
  • 143. Direc&onality Each en(ty in a rela(onship may have a pointer to the other en(ty +------------+ +--------------+ | | | | | Employee +-------------> Department | | | * 1 | | +------------+ +--------------+
  • 144. Direc&onality If only one en)ty has a pointer to the other, the rela)onship is said to be unidirec(onal +------------+ +--------------+ | | | | | Employee +-------------> Department | | | * 1 | | +------------+ +--------------+
  • 145. Direc&onality When each en(ty points to the other, the rela(onship is said to be bidirec'onal +------------+ +--------------+ | | | | | Employee <-------------> Department | | | * 1 | | +------------+ +--------------+
  • 146. Direc&onality All rela'onships in JPA are unidirec(onal. A bidirec'onal rela'onship has to be intended as a pair of unidirec'onal mappings +------------+ * 1 +--------------+ | +-------------> | | Employee | | Department | | <-------------+ | +------------+ * 1 +--------------+
  • 147. Role Depending on the direc.onality, we can iden.fy the en.ty playing the role of source and the en.ty playing the role of target +------------+ +--------------+ | | | | | Employee +-------------> Department | | | * 1 | | +------------+ +--------------+
  • 148. Role Employee and Department are involved in a unidirec(onal rela(onship +------------+ +--------------+ | | | | | Employee +-------------> Department | | | * 1 | | +------------+ +--------------+
  • 149. Role Employee is the source en)ty +------------+ +--------------+ | | | | | Employee +-------------> Department | | | * 1 | | +------------+ +--------------+
  • 150. Role Department is the target en(ty +------------+ +--------------+ | | | | | Employee +-------------> Department | | | * 1 | | +------------+ +--------------+
  • 151. Cardinality Each role in the rela-onship has its own cardinality • Many-to-one: many source en..es, one target en.ty • One-to-many: one source en.ty, many target en..es • One-to-one: one source en.ty, one target en.ty • Many-to-many: many source en..es, many target en..es
  • 152. Ownership In the database, almost every rela2onship is implemented by introducing a column that refers to a key in another table
  • 153. Ownership Such a column is usually called the join column
  • 154. Ownership The underlying Employee table has a join column containing the Department primary key ┌─────────────┬───────────────┬─────────────┬──────────────┐ │ employeeId │ name │ gender │ departmentId │ ├─────────────┼───────────────┼─────────────┼──────────────┤ │ 12 │ Jon Snow │ male │ 7 │ └─────────────┴───────────────┴─────────────┴──────────────┘
  • 155. Ownership The en&ty holding the join column is called the owner of the rela&onship and its side is called the owning side ┌─────────────┬───────────────┬─────────────┬──────────────┐ │ employeeId │ name │ gender │ departmentId │ ├─────────────┼───────────────┼─────────────┼──────────────┤ │ 12 │ Jon Snow │ male │ 7 │ └─────────────┴───────────────┴─────────────┴──────────────┘
  • 156. Ownership Employee is the owner of the rela,onship +------------+ +--------------+ | | | | | Employee +-------------> Department | | | * 1 | | +------------+ +--------------+
  • 157. Many-to-one mappings In a many-to-one mapping, the owner of the rela2onship is the source en2ty @Entity public class Employee { @Id private int id; @ManyToOne private Department department; }
  • 158. Many-to-one mappings A many-to-one mapping is defined by annota2ng the source en)ty with the @ManyToOne annota2on @Entity public class Employee { @Id private int id; @ManyToOne private Department department; }
  • 159. One-to-many mappings In a one-to-many mapping, the owner of the rela2onship is the target en2ty @Entity public class Department { @Id private int id; @OneToMany(mappedBy="department") private List<Employee> employees; }
  • 160. One-to-many mappings Therefore, the @OneToMany annota,on must come with the mappedBy a3ribute @Entity public class Department { @Id private int id; @OneToMany(mappedBy="department") private List<Employee> employees; }
  • 161. One-to-many mappings The mappedBy a&ribute indicates that the owning side resides at the other end of the rela5onship @Entity public class Department { @Id private int id; @OneToMany(mappedBy="department") private List<Employee> employees; }
  • 162. One-to-one mappings In a one-to-one mapping, the owner can be either the source or the target en4ty @Entity public class Employee { @Id private int id; @OneToOne private ParkingSpace parkingSpace; }
  • 163. One-to-one mappings A one-to-one mapping is defined by annota2ng the owner en'ty with the @OneToOne annota2on @Entity public class Employee { @Id private int id; @OneToOne private ParkingSpace parkingSpace; }
  • 164. One-to-one mappings If the one-to-one mapping is bidirec4onal, the inverse side of the rela4onship needs to be specified as well @Entity public class ParkingSpace { @Id private int id; @OneToOne(mappedBy="parkingSpace") private Employee employee; }
  • 165. One-to-one mappings In the non-owner en+ty, the @OneToOne annota+ons must come with the mappedBy element @Entity public class ParkingSpace { @Id private int id; @OneToOne(mappedBy="parkingSpace") private Employee employee; }
  • 166. Many-to-many mappings In a many-to-many mapping there is no join column. The only way to implement such a mapping is by means of a join table ┌─────────────┬─────────────┐ │ employeeId │ projectId │ ├─────────────┼─────────────┤ │ 12 │ 7 │ ├─────────────┼─────────────┤ │ 1 │ 33 │ ├─────────────┼─────────────┤ │ 76 │ 7 │ └─────────────┴─────────────┘
  • 167. Many-to-many mappings Therefore, we can arbitrarily specify as owner either the source or the target en6ty @Entity public class Employee { @Id private int id; @ManyToMany private List<Project> projects; }
  • 168. Many-to-many mappings If the many-to-many mapping is bidirec5onal, the inverse side of the rela5onship needs to be specified as well @Entity public class Project { @Id private int id; @ManyToMany(mappedBy="projects") private List<Employee> employees; }
  • 169. Many-to-many mappings In the non-owner en+ty, the @ManyToMany annota+on must come with the mappedBy element @Entity public class Project { @Id private int id; @ManyToMany(mappedBy="projects") private List<Employee> employees; }
  • 170. Cascading opera.ons By default, every EntityManager’s opera2on applies only to the en2ty object supplied as the opera2on argument
  • 171. Cascading opera.ons The opera)on will not cascade to other en))es that have a rela)onship with the en)ty that is being operated on
  • 172. Cascading opera.ons For some opera*ons, this is usually the desired behavior // we do not want to also delete her department entityManager.remove(employ);
  • 173. Cascading opera.ons For some other opera,ons, this is instead an unfortunate circumstances // we want to persist also the related department entityManager.persist(employ);
  • 174. Cascading opera.ons If a transient en+ty has a rela+onship with another transient en+ty, the two must be persisted together
  • 175. Manually cascading A naive approach would be to manually cascade related en33es Employee emp = new Employee(...); Department dep = new Department(...); emp.setDepartment(dep); entityManager.persist(dep); entityManager.persist(emp);
  • 176. Manually cascading This is however inconvenient Employee emp = new Employee(...); Department dep = new Department(...); emp.setDepartment(dep); entityManager.persist(dep); entityManager.persist(emp);
  • 177. Manually cascading We do not want to explicitly persist the Department instance Employee emp = new Employee(...); Department dep = new Department(...); emp.setDepartment(dep); entityManager.persist(dep); entityManager.persist(emp);
  • 178. Cascading opera.ons The cascade a&ribute allows defining when opera5ons such as persist() should be automa&cally cascaded across rela5onships @Entity public class Employee { @ManyToOne(cascade=CascadeType.PERSIST) Department department; }
  • 179. Cascading opera.ons The cascade a&ribute allows defining when opera5ons such as persist() should be automa&cally cascaded across rela5onships Employee emp = new Employee(...); Department dep = new Department(...); emp.setDepartment(dep); entityManager.persist(emp); // dep gets persisted as well
  • 180. Cascading opera.ons You need to be sure that the Department instance has been set on the Employee instance before persist()-ing the la4er Employee emp = new Employee(...); Department dep = new Department(...); emp.setDepartment(dep); entityManager.persist(emp); // dep gets persisted as well
  • 181. Cascading opera.ons The cascade a&ribute accepts several possible values coming from the CascadeType enumera4on • PERSIST, REFRESH, REMOVE, MERGE and DETACH
  • 182. Cascading opera.ons The constant ALL is a shorthand for declaring that all five opera4ons should be cascaded @Entity public class Employee { @ManyToOne(cascade=CascadeType.ALL) Department department; }
  • 183. Cascading opera.ons As with rela,onships, cascade se3ngs are unidirec(onal @Entity public class Employee { @Id private int id; @ManyToOne(cascade=CascadeType.PERSIST) Department department; } @Entity public class Department { @Id private int id; @OneToMany(cascade=CascadeType.PERSIST, mappedBy="department") private List<Employee> employees; }
  • 184. Cascading opera.ons They must be explicitly set on both sides of a rela3onship if the same behavior is intended for both situa3ons @Entity public class Employee { @Id private int id; @ManyToOne(cascade=CascadeType.PERSIST) Department department; } @Entity public class Department { @Id private int id; @OneToMany(cascade=CascadeType.PERSIST, mappedBy="department") private List<Employee> employees; }
  • 185. Lazy loading In many real situa.ons, certain por.ons of an en.ty will be seldom accessed +------------+ +--------------+ | | | | | Employee <-------------> Department | | | * 1 | | +------------+ +--------------+
  • 186. Lazy loading Lazy loading is a design pa*ern that allows deferring the fetching of data un4l they are actually needed
  • 187. Lazy loading The employees a&ribute may not be loaded each 3me a Department is loaded @Entity public class Department { @Id private int id; @OneToMany(fetch=FetchType.LAZY, ...) private List<Employee> employees; }
  • 188. Lazy loading Lazy loading can improve performance because of the reduced amount of SQL that gets executed
  • 189. Lazy loading In case of bidirec.onal rela.onships, the fetch mode might be lazy on one side but eager on the other @Entity public class Employee { @Id private int id; @ManyToOne Department department; } @Entity public class Department { @Id private int id; @OneToMany(mappedBy="department", fetch=FetchType.LAZY) private List<Employee> employees; }
  • 190. Lazy loading As a ma&er of fact, rela/onships are o4en accessed in different ways depending on the direc/on from which naviga/on occurs @Entity public class Employee { @Id private int id; @ManyToOne Department department; } @Entity public class Department { @Id private int id; @OneToMany(mappedBy="department", fetch=FetchType.LAZY) private List<Employee> employees; }
  • 191. Lazy loading Note that the direc,ve to lazily fetch an a/ribute is meant only to be a hint to the persistence provider @Entity public class Department { @Id private int id; @OneToMany(fetch=FetchType.LAZY, ...) private List<Employee> employees; }
  • 192. Lazy loading The provider is not required to honor the request, as the behavior of the en4ty is not compromised if data get eagerly loaded @Entity public class Department { @Id private int id; @OneToMany(fetch=FetchType.LAZY, ...) private List<Employee> employees; }
  • 193. Lazy loading The converse is not true: specifying that an a3ribute be eagerly fetched might be cri9cal to access the en9ty once detached @Entity public class Employee { @Id private int id; @ManyToOne Department department; }
  • 194. Querying the data source
  • 195. Querying the data source JPA provides three methods to retrieve en11es • EntityManager.find() • Query API • Criteria API
  • 197. Java Persistence Query Language The Java Persistence Query Language (JPQL) is a pla0orm- independent object-oriented query language defined as part of the JPA specificaBon
  • 198. Java Persistence Query Language The main difference with SQL is that • JPQL operates on classes and objects • SQL operates on tables, columns and rows
  • 199. Java Persistence Query Language Therefore, the outcome of a JPQL query is a collec%on of objects, rather than a list of tuples
  • 200. Java Persistence Query Language Note that JPQL syntax looks like SQL, but JPQL is not SQL SELECT e FROM Employee e
  • 201. JQPL statements JPQL supports three types of statements • SELECT statements retrieve en,,es or en,ty-related data • UPDATE statements update one or more en,,es • DELETE statements delete one or more en,,es
  • 202. FROM clause The FROM clause defines the domain for the query, that is, the en55es that will be used in the query SELECT e FROM Employee e
  • 203. FROM clause Employee is the domain that we want to query, and e is intended as an iden(fier of type Employee SELECT e FROM Employee e
  • 204. FROM clause Iden%fiers can be used in other clauses of the same query (e.g., WHERE clauses) SELECT e FROM Employee e WHERE e.name = "Jon Snow"
  • 205. Path Expressions Given an iden)fier, we can use dot nota'on to access a specific field of the en)ty SELECT e FROM Employee e WHERE e.phones is NOT EMPTY
  • 206. Path Expressions Such expressions are known as path expressions SELECT e FROM Employee e WHERE e.phones is NOT EMPTY
  • 207. Path Expressions Path expressions are commonly used in • WHERE clauses so as to narrow the domain for a query • ORDER BY clauses so as to order the retrieved result set
  • 208. JOIN operator In many common situa-ons, there is the need to join two or more en--es based on their rela-onship
  • 209. JOIN operator To this end, joins can be specified either in the WHERE clause... SELECT p.number FROM Employee e, Phone p WHERE e = p.employee AND e.department.name = 'NA42'
  • 210. JOIN operator ...or in the FROM clause by means of the JOIN operator SELECT p.number FROM Employee e JOIN e.phones p WHERE e.department.name = 'NA42'
  • 211. Query API JPQL queries are executed by means of the Query API
  • 212. Query API The required steps to create a JPA query are similar to those of a tradi7onal JDBC query ┌────────────────────────────────┬─────────────────────────────────────────┐ │///////////// JDBC /////////////│/////////////// Query API //////////////│ ├────────────────────────────────┼─────────────────────────────────────────┤ │ Obtain a database connection │ Obtain an EntityManager instance │ ├────────────────────────────────┼─────────────────────────────────────────┤ │ Create a query statement │ Create a query statement │ ├────────────────────────────────┼─────────────────────────────────────────┤ │ Execute the query │ Execute the query │ ├────────────────────────────────┼─────────────────────────────────────────┤ │ Retrieve the result (tuples) │ Retrieve the result (objects) │ └────────────────────────────────┴─────────────────────────────────────────┘
  • 213. Query API The Query API supports two types of queries • Named queries, which are meant to be stored and reused • Dynamic queries, which are created and executed on the fly
  • 214. Named query Named query are stored on the en'ty @Entity @NamedQuery( name = "findSalaries", query = "SELECT e.salary FROM Employee") public class Employee { ... }
  • 215. Named query Any query that is used in mul$ple components of the applica4on is a candidate for a named query @Entity @NamedQuery( name = "findSalaries", query = "SELECT e.salary FROM Employee") public class Employee { ... }
  • 216. Named query Named queries can enhance performance because they are prepared once and then efficiently reused @Entity @NamedQuery( name = "findSalaries", query = "SELECT e.salary FROM Employee") public class Employee { ... }
  • 217. Named query Named query are globally scoped and instan/ated by name TypedQuery<Integer> query = entityManager .createNamedQuery("findSalaries");
  • 218. Named query That is, named query instances can be created from any component that can access the persistence unit TypedQuery<Integer> query = entityManager .createNamedQuery("findSalaries");
  • 219. Named query Consequently, a named queries must have a unique name in the whole persistence unit @Entity @NamedQuery(name = "findSalaries", query = "...") public class Employee { ... }
  • 220. Dynamic query Dynamic queries are created at run 0me, and they are normally used when the query depends on the context String stmt = "SELECT e FROM Employee e WHERE e.name = :empName"; TypedQuery<Employee> query = entityManager.createQuery(stmt);
  • 221. Dynamic query A dynamic query can be created wherever the EntityManager is available. The only requirement is to pass a valid JPQL statement String stmt = "SELECT e FROM Employee e WHERE e.name = :empName"; TypedQuery<Employee> query = entityManager.createQuery(stmt);
  • 222. Execu&ng queries A TypedQuery object represents a query instance String stmt = "SELECT e FROM Employee e WHERE e.name = :empName"; TypedQuery<Employee> query = entityManager.createQuery(stmt);
  • 223. Execu&ng queries The TypedQuery interface defines several methods for parameterizing and execu.ng the query ┌────────────────────────────────────────────┬─────────────────────────────────────────┐ │///////////// Method signature /////////////│////////////// Description //////////////│ ├────────────────────────────────────────────┼─────────────────────────────────────────┤ │ public List getResultList(); │ Retrieves the result set │ ├────────────────────────────────────────────┼─────────────────────────────────────────┤ │ public │ Sets the maximum number of objects to be│ │ TypedQuery<T> setMaxResults(int maxResult);│ retrieved │ ├────────────────────────────────────────────┼─────────────────────────────────────────┤ │ public │ │ │ TypedQuery<T> setParameter(int position, │ Sets the value for a positional │ │ Object value); │ parameter │ │ │ │ ├────────────────────────────────────────────┼─────────────────────────────────────────┤ │ public │ │ │ TypedQuery<T> setParameter(String name, │ Sets the value for a named parameter │ │ Object value); │ │ └────────────────────────────────────────────┴─────────────────────────────────────────┘
  • 224. Parameters The number of en,,es retrieved in a query may be limited by specifying a WHERE clause, which can be parameterized SELECT e.salary FROM Employee e WHERE e.name = :empName
  • 225. Parameters In JPA, There exist two types of parameters • Posi&onal parameters • Named parameters
  • 226. Parameters Before execu*ng a query, all parameters need to be set SELECT e.salary FROM Employee e WHERE e.name = :empName
  • 227. Parameters This can be done using the TypedQuery’s setParameter() method SELECT e.salary FROM Employee e WHERE e.name = :empName
  • 228. Posi%onal parameters Posi%onal parameters are iden(fied by number String stmt = "SELECT i FROM Item i WHERE i.initialPrice = ?1"; TypedQuery<Item> query = em.createQuery(stmt); query.setParameter(1, 100.00); List<Item> items = query.getResultList();
  • 229. Named parameters Named parameters are iden(fied by label String stmt = "SELECT i FROM Item i WHERE i.initialPrice = :price"; TypedQuery<Item> query = em.createQuery(stmt); query.setParameter("price", 100.00); List<Item> items = query.getResultList();
  • 231. The problem with the Query API The Query API cannot verify the correctness of a JPQL query before its actual execu:on // This will compile despite the incorrect JQPL query TypedQuery<Employee> query = em.createQuery("SELECT e FROM Employee t");
  • 232. The problem with the Query API We would much prefer to let the compila(on fail in the presence of incorrect JQPL queries
  • 233. Criteria API The Criteria API provides a way of crea6ng type-safe queries, i.e., queries the compiler can check at compile-2me
  • 234. Crea%ng a new query The steps for crea-ng a Criteria API-based query are 1. Obtaining a CriteriaBuilder object 2. Using this instance to compose a CriteriaQuery object 3. Execu9ng the query
  • 235. Crea%ng a new query The CriteriaQuery instance represents the query we would like to execute
  • 236. Crea%ng a new query The CriteriaBuilder interface provides methods for all keywords, operators, and func8ons from JPQL public interface CriteriaBuilder { CriteriaQuery<T> createQuery(Class<T> resultClass); Predicate and(Expression<Boolean> x, Expression<Boolean> y); Predicate or(Expression<Boolean> x, Expression<Boolean> y); Predicate isNotNull(Expression<?> x); ... }
  • 237. Crea%ng a new query That is, the CriteriaBuilder is a factory for all the individual pieces of the query public interface CriteriaBuilder { CriteriaQuery<T> createQuery(Class<T> resultClass); Predicate and(Expression<Boolean> x, Expression<Boolean> y); Predicate or(Expression<Boolean> x, Expression<Boolean> y); Predicate isNotNull(Expression<?> x); ... }
  • 238. Crea%ng a new query A CriteriaBuilder object can be obtained from an EntityManager instance CriteriaBuilder cb = entityManager.getCriteriaBuilder();
  • 239. Crea%ng a new query Once available, a CriteraBuilder can be used to create CriteriaQuery objects CriteriaQuery<Employee> c = cb.createQuery(Employee.class);
  • 240. Crea%ng a new query To ensure type-safety, the CriteriaQuery's type parameter should be set to the result type of the query CriteriaBuilder cb = entityManager.getCriteriaBuilder(); CriteriaQuery<Employee> c = cb.createQuery(Employee.class);
  • 241. Root object Every CriteriaQuery defines at least one Root object, whose role is analogous to that of an iden%fier in a JPQL query Root<Employee> e = c.from(Employee.class); c.select(e);
  • 242. Root object Every CriteriaQuery defines at least one Root object, whose role is analogous to that of an iden%fier in a JPQL query SELECT e FROM Employee e
  • 243. Root object Like JPQL iden+fiers, Root objects are commonly used in SELECT and WHERE clauses Root<Employee> e = c.from(Employee.class); c.select(e);
  • 244. Canonical metamodel The Criteria API ensures type-safety by means of a canonical metamodel @StaticMetamodel(Employee.class) public class Employee_ {...} @StaticMetamodel(Department.class) public class Department_ {...} @StaticMetamodel(Project.class) public class Project_ {...}
  • 245. Canonical metamodel The canonical metamodel of a persistence unit is a descrip1on of the persistent type, state, and rela1onships of en11es @StaticMetamodel(Employee.class) public class Employee_ {...} @StaticMetamodel(Department.class) public class Department_ {...} @StaticMetamodel(Project.class) public class Project_ {...}
  • 246. Canonical metamodel In prac(ce, the canonical metamodel is implemented as a series of classes that mirror the en((es in the domain model @StaticMetamodel(Employee.class) public class Employee_ {...} @StaticMetamodel(Department.class) public class Department_ {...} @StaticMetamodel(Project.class) public class Project_ {...}
  • 247. Canonical metamodel Such metamodel classes provide access to metadata about the associated domain class @StaticMetamodel(Employee.class) public class Employee_ { public static volatile SingularAttribute<Employee, Integer> id; public static volatile SingularAttribute<Employee, String> name; public static volatile SingularAttribute<Employee, String> salary; public static volatile SingularAttribute<Employee, Department> dept; public static volatile SingularAttribute<Employee, Address> address; public static volatile CollectionAttribute<Employee, Project> project; }
  • 248. Canonical metamodel For each en*ty E, there should exist a metamodel class E_ in the same package @StaticMetamodel(Employee.class) public class Employee_ { public static volatile SingularAttribute<Employee, Integer> id; public static volatile SingularAttribute<Employee, String> name; public static volatile SingularAttribute<Employee, String> salary; public static volatile SingularAttribute<Employee, Department> dept; public static volatile SingularAttribute<Employee, Address> address; public static volatile CollectionAttribute<Employee, Project> project; }
  • 249. Canonical metamodel Each metamodel class must be annotated with the @StaticMetamodel annota2on @StaticMetamodel(Employee.class) public class Employee_ { public static volatile SingularAttribute<Employee, Integer> id; public static volatile SingularAttribute<Employee, String> name; public static volatile SingularAttribute<Employee, String> salary; public static volatile SingularAttribute<Employee, Department> dept; public static volatile SingularAttribute<Employee, Address> address; public static volatile CollectionAttribute<Employee, Project> project; }
  • 250. Path expressions Root objects and metamodel classes are employed together to form path expressions Root<Employee> e = c.from(Employee.class); c.select( e.get(Employee_.department).get(Department_.id) );
  • 251. Path expressions The Root object and the metamodel classes are employed together to form path expressions SELECT e.department.id FROM Employee e
  • 252. JOIN opera'on Joins can be performed by calling the join() method on the Root object Root<Employee> e = c.from(Employee.class); Join<Employee, Phone> p = e.join(Employee_.phones); c.select(p.get(Phone_.number)) c.where(cb.equal(e.get(Employee_.name), "Jon Snow"));
  • 253. JOIN opera'on Joins can be performed by calling the join() method on the Root object SELECT p.number FROM Employee e JOIN e.phones p WHERE e.name = "Jon Snow"
  • 254. JOIN opera'on Note that the resul,ng Join object behaves like a Root object, meaning that joins can be cascaded
  • 255. WHERE clause WHERE clauses can be used to narrow the result set Root<Employee> e = c.from(Employee.class); c.select(e); c.where(cb.equal(e.get(Employee_.name), "Jon Snow"));
  • 256. WHERE clause WHERE clauses can be used to narrow the result set SELECT e FROM Employee e WHERE e.name = "Jon Snow"
  • 257. WHERE clause Each condi*on in a WHERE clause is expressed as a Predicate instance // Incremental construction Predicate predicates = cb.conjunction(); predicates = cb.and(predicates, cb.equal(e.get(Employee_.name), "Jon Snow")); predicates = cb.and(predicates, cb.equal(e.get(Employee_.dept).get(Department_.id), 7)); c.where(predicates);
  • 258. WHERE clause Predicates can be combined by means of AND or OR operators // Incremental construction Predicate predicates = cb.conjunction(); predicates = cb.and(predicates, cb.equal(e.get(Employee_.name), "Jon Snow")); predicates = cb.and(predicates, cb.equal(e.get(Employee_.dept).get(Department_.id), 7)); c.where(predicates);
  • 259. WHERE clause Predicates can be combined by means of AND or OR operators // List-based construction List<Predicate> predicates = new ArrayList<>(); predicates.add(cb.equal(e.get(Employee_.name), "Jon Snow")); predicates.add(cb.equal(e.get(Employee_.dept).get(Department_.id), 7)); Predicate[] predArray = predicates.toArray(new Predicate[predicates.size()]); c.where(cb.and(predArray));
  • 260. WHERE clause Predicates can be combined by means of AND or OR operators SELECT e FROM Employee e WHERE e.name = "Jon Snow" AND d.department.id = 7
  • 261. Defining parameters To parameterize queries using the Criteria API, a ParameterExpression object must be created ParameterExpression<String> deptName = cb.parameter(String.class, "deptName");
  • 262. Execu&ng queries Once the query is composed, it is possible to obtain a TypedQuery object out of a CriteriaQuery object TypedQuery<Employee> q = entityManager.createQuery(c);
  • 263. Execu&ng queries As with any TypedQuery, parameters need to be provided before the actual execu9on TypedQuery<Employee> q = em.createQuery(c); q.setParameter("deptName", "NA42") return q.getResultList();
  • 265. References • Java Community Process, JPA 2.1 specifica:on • Hibernate Community Documenta:on, EntityManager • Hibernate Community Documenta:on, Transac:ons and Concurrency • Wikipedia, Data Access Object • SpringSource, Spring Framework Reference
  • 266. References • Hibernate Wiki, Data Access Objects • Hibernate Wiki, Open Session in View pa9ern • Hibernate Community Documenta>on, Metamodel • Hibernate Community Documenta>on, Criteria Queries • OpenJPA, JPA Concepts
  • 267. References • M. Keith, M. Schincariol, Pro JPA 2, Mastering The Java Persistence API, Apress Media LLC • D. Panda et al., EJB3 In AcCon, Manning PublicaCons • C. Baver, G.King, Java Persistence With Hibernate, Manning PublicaCons • S. Guruzu, G. Mak, Hibernate Recipes - A Problem-SoluCon Approach, Apress Media LLC
  • 268. References • A.L. Rubinger, B.Burke, Enterprise JavaBeans 3.1, O’Reilly Media • R.M. Reese, EJB 3.1 Cookbook, Packt Publishing • Craig Walls, Spring in AcGon (3rd EdiGon), Manning PublicaGons • Willie Wheeler, Spring in PracGce, Manning PublicaGons
  • 269. Topics not covered • Physical annota.ons • Cascading policies other than PERSIST • Vender-based APIs (e.g., Hibernate APIs) • Advanced JPQL and Criteria API-based queries • Long units of work