Orm Jpa
Orm Jpa
Sadegh Aliakbary
Table of Contents
Java Database Connectivity (JDBC)
Object Relation Mapping
Java Persistence API (JPA)
Entity Classes
DAO and Generic DAO patterns
Object Relations (Many-to-One, One-to-Many, Many-to-Many)
JPQL
Querying with the Criteria API
Test JPA and DAO classes using spring
JPA and Spring
Transaction Management (by Spring Transaction)
JPA www.asta.ir 2
Getting Ready
JPA www.asta.ir 3
Start the Exercise Project
Review the Layers (Service, Manager, DAO)
Changes needed in Tomcat
Context.xml
JPA www.asta.ir 4
Java Database Connectivity (JDBC)
JPA www.asta.ir 5
JDBC
JDBC API provides a standard database-independent interface to
interact with RDBMSs.
Using JDBC API relieves you of the effort to learn specific protocols for
different databases
But the SQL syntax of different DBs may still differ
JPA www.asta.ir 6
JDBC Driver
The collection of implementation classes
that is supplied by a vendor
to interact with a specific database
The ‘JDBC driver’ is used to connect to the RDBMS.
Is usually delivered as a JAR file
E.g., Oracle JDBC driver, MySQL JDBC driver
JPA www.asta.ir 7
The Architecture of JDBC
JPA www.asta.ir 8
JDBC Example
//Class.forName("com.mysql.jdbc.Driver"); Now: Optional
String SQL = "SELECT * FROM classes";
try (
Connection conn = DriverManager.getConnection(
"jdbc:mysql://localhost/cse3330a",
"root", "123");
Statement stmt = conn.createStatement();
ResultSet rs = stmt.executeQuery(SQL)
) {
while (rs.next()) {
System.out.println(rs.getString("prof"));
}
}
JPA www.asta.ir 9
JDBC
To connect to a database:
1. Obtain the JDBC driver class files (JAR)
add them to the CLASSPATH.
2. Construct a connection URL.
3. Use the static ‘getConnection()’ method of ‘DriverManager’ to
establish a connection.
4. Create statements on the connection
and execute SQL queries
JPA www.asta.ir 10
‘Statement’ interface
‘execute()’ method
is used to execute a SQL statement which does not return a value,
such as ‘CREATE TABLE’.
‘executeUpdate()’ method
is used for SQL that updates a database,
as in ‘INSERT’, ‘UPDATE’ and ‘DELETE’ SQL statements.
It returns the number of rows affected.
‘executeQuery()’
is used for SQL that produces a resultset,
as in ‘SELECT’ SQL statements.
JPA www.asta.ir 11
Commit & Rollback
The ‘auto-commit’ property for the ‘Connection’ object
is set to ‘true’ by default.
JPA www.asta.ir 12
AutoCommit
try {
Connection conn = get the connection…
conn.setAutoCommit(false);
Statement stmt = conn.createStatement();
stmt.executeUpdate(sql1);
stmt.executeUpdate(sql2);
conn.commit();
conn.close();
}
catch (SQLException e){
conn.rollback();
e.printStackTrack();
conn.close();
}
JPA www.asta.ir 13
ResultSet Example
Connection conn = …//get a Connection object …
Statement stmt = conn.getStatement();
String sql = “select person_id, first_name,”+
“last_name,dob,income from person”;
ResultSet rs = stmt.executeQuery(sql);
while (rs.next()) {
int personID=rs.getInt(1);
String firstName=rs.getString(2);
String lastName = rs.getString(3);
java.sql.Date dob = rs.getDate(4);
double income = rs.getDouble(5);
//do something with the retrieved values from the cols.
}
JPA www.asta.ir 14
Overview of JDBC Concepts
JDBC Driver
Connection
Statement
ResultSet
Commit & rollback
JPA www.asta.ir 15
JDBC Pros and Cons
Pros
Clean and simple SQL processing
Cons
Complex if it is used in large projects
No encapsulation
JPA www.asta.ir 16
JDBC Exercise
Implement save and load methods in ContactDAO
Using JDBC
JPA www.asta.ir 17
Other Concepts in JDBC
PreparedStatement
And CallableStatement
RowSet
SQL Injection
JPA www.asta.ir 18
Object Relational Mapping
JPA www.asta.ir 19
What is ORM?
In relational databases:
business entities are represented as tables + relationships
In object-oriented languages:
business entities are represented as classes
Object relational mapping frameworks (ORMs) are used for:
mapping business entities to database tables
OO
ORM Relational
Programming
Framework Database
Language
JPA www.asta.ir 20
ORM – Example
JPA www.asta.ir 21
Simple Scenarios (Pseudocode)
Person person = new Person(“Ali Alavi”, 22, “0078934563”);
orm.save(person);
JPA www.asta.ir 23
How does an ORM framework work? (cont’d)
Now the ORM framework knows that:
ir.hr.Person class corresponds to PERSON table
EclipseLink – https://eclipse.org/eclipselink/
ORM for Java by Eclipse foundation
JPA www.asta.ir 27
History
Java v1.1 (1997) included JDBC
J2EE v1.2 (1999) introduced EJB Entity beans
Entity beans introduced, so others did it better
Hibernate (2001)
JPA v1.0 (JSR 220) was released in 2006
JPA v2.0 (JSR 317) was released in 2009
JPA www.asta.ir 28
Introduction to JPA
JPA www.asta.ir 29
About JPA
What is Java Persistence API (JPA)?
Database persistence technology for Java (official standard)
Object-relational mapping (ORM) technology
Operates with POJO entities with annotations or XML mappings
Implemented by many ORM engines: Hibernate, EclipseLink, …
JPA maps Java classes to database tables
Maps relationships between tables as associations between classes
Provides CRUD functionality and queries
Create, read, update, delete + queries
JPA www.asta.ir 30
Entities in JPA
A JPA entity is just a POJO class
The java classes corresponding to persistent data
E.g., User, Author, Book, etc.
Name more?!
Non-final fields/properties, no-arguments constructor
No required interfaces
No requirement for business or callback interfaces
Direct field or property-based access
Getter/setter can contain logic (e.g. validation)
JPA www.asta.ir 31
The Minimal JPA Entity: Class Definition
Must be indicated as an Entity
@Entity annotation on the class:
@Entity
public class Employee {
…
}
JPA www.asta.ir 32
The Minimal JPA Entity: Primary Key
Must have a persistent identifier (primary key):
@Entity
public class Employee {
@Id int id;
JPA www.asta.ir 34
Primary Key Identifier Generation
Identifiers can be generated in the database
@GeneratedValue on the ID field
Managed by EntityManager
The PC change as a result of operations on EntityManager API
JPA www.asta.ir 39
The EntityManager
Client-visible object for operating on entities
API for all the basic persistence operations (CRUD)
JPA www.asta.ir 40
Persistence Context (PC) and Entities
Application Persistence
Context
EntityManager
MyEntity A
MyEntity C
MyEntity a MyEntity B
MyEntity b
Entities
Entity
state
JPA www.asta.ir 41
Overview of PC
Entities are managed by an EntityManager instance using persistence
context
Each EntityManager instance is associated with a persistence context
Within the persistence context, the entity instances and their lifecycle
are managed
A persistence context is like a cache which contains a set of persistent
entities
So once the transaction is finished, all persistent objects are detached
from the EntityManager's persistence context and are no longer
managed
JPA www.asta.ir 42
Operations on Entities
EntityManager API
persist() – persists given entity object into the DB
(SQL INSERT)
merge() – updates given entity in the DB
(SQL UPDATE)
remove() – deletes given entity into the DB
(SQL DELETE by PK)
JPA www.asta.ir 43
EntityManager.flush() method
flush()
Forces changes in the PC to be sent to the database
It is automatically called on transaction commit (but not vice
versa)
It does not call transaction commit. The transaction may be rolled-
back
Note:
Entitymanager.flush() vs EntityManager.getTransaction().commit
JPA www.asta.ir 44
Other EntityManager Operations
find() – execute a simple query by PK
(SQL SELECT by PK)
createNativeQuery()
Creates an instance for an SQL query
JPA www.asta.ir 45
EntityManager.persist()
Insert a new entity instance into the database
Save the persistent state of the entity and any owned relationship
references
Entity instance becomes managed
public Customer createCustomer(int id, String name) {
Customer cust = new Customer(id, name);
entityManager.persist(cust);
return cust;
}
JPA www.asta.ir 46
Updating an Entity
1- By just changing a managed* entity
And committing the transaction
JPA www.asta.ir 47
find() and remove()
find()
Obtain a managed entity instance (SQL SELECT by PK)
remove()
Delete a managed entity by PK
JPA www.asta.ir 49
EntityManagerFactory Class
javax.persistence.EntityManagerFactory
Obtained by the Persistance
Creates EntityManager for a named
persistence unit or configuration
In Java SE environment the persistence unit configuration is
defined in the META-INF/persistence.xml file
JPA www.asta.ir 50
Sample Config: META-INF/persistence.xml
<?xml version="1.0" encoding="UTF-8"?>
<persistence xmlns="http://java.sun.com/xml/ns/persistence"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="1.0">
<persistence-unit name="hellojpa">
<class>model.Message</class>
<properties>
<property name="ConnectionURL"
value="jdbc:derby:messages-db;create=true"/>
<property name="ConnectionDriverName"
value="org.apache.derby.jdbc.EmbeddedDriver"/>
<property name="ConnectionUserName" value=""/>
<property name="ConnectionPassword" value=""/>
</properties>
</persistence-unit>
</persistence>
JPA www.asta.ir 51
Automatic Table Generation
JPA may be configured to automatically create the database
tables
During application deployment
javax.persistence.schema-generation.database.action property
Configures the behavior of JPA for table generation
JPA www.asta.ir 52
javax.persistence.schema-generation.database.action
<persistence ...>
<persistence-unit name="WISE">
...
<properties>
...
<property name="javax.persistence.schema-generation.database.action"
value="drop-and-create"/>
</properties>
</persistence-unit>
</persistence>
@PersistenceContext
private EntityManager entityManager;
JPA www.asta.ir 59
DAO and Generic DAO Patterns
JPA www.asta.ir 60
Layering
Enterprise applications usually are
Presentation Layer
divided into logical layers
Three-layer Service Layer
UI, Business Logic, Data
Manager Layer
Four-Layer
UI, Service, Business Logic, Data
DAO Layer
Data Layer: Collection of classes related to
data access (DAO layer) DB
JPA www.asta.ir 61
Data Access Object Pattern (DAO)
(Entity)
JPA www.asta.ir 62
DAO
Abstracts the details of the underlying persistence mechanism
Hides the implementation details of the data source from its
clients
Loose coupling between core business logic and persistence
mechanism
JPA www.asta.ir 63
1. Write Entity Classes
@Entity @Table(name="WISE_CONTACT")
public class ContactEntity {
Long id;
String name;
@Id
@Column(name = "CONTACT_ID")
@GeneratedValue(strategy=GenerationType.AUTO)
public Long getId() {
return id;
}
public void setId(Long id) { this.id = id; }
@Basic(fetch=FetchType.EAGER)
@Column(name="NAME_")
public String getName() {
return name;
}
public void setName(String name) { this.name = name; }
}
JPA www.asta.ir 64
2. DAO implementations
@Named("contactDao")
public class ContactDao {
@PersistenceContext
private EntityManager entityManager;
JPA
and implement the DAO interface
www.asta.ir 66
Generic DAO Example
class AbstractJpaDAO<T extends BaseEntity<U>, U extends Serializable>{
@PersistenceContext
private EntityManager entityManager;
public void save(T entity) {
etityManager.persist(entity);
}
public T load(U id) {
return (T) etityManager.find(getEntityClass(), id);
}
public abstract Class<T> getEntityClass() ;
//and find, search, update, many other methods.
}
public class ContactDao extends AbstractJpaDAO<ContactEntit, Long>{
public Class<ContactEntity> getEntityClass() {
return ContactEntity.class;
}
}
JPA www.asta.ir 67
Exercise on JPA Basics
Implement find method in ContactDAO
Using JPA
JPA www.asta.ir 68
Transaction Management
(by Spring Transaction)
Programmatic Transactions
entityTransaction.begin();
entityManager.persist(entity);
entityTransaction.commit();
}
JPA www.asta.ir 70
Using Spring @Transactional
With Spring @Transactional, the transaction management is made simple
@Transactional
public void businessLogic() {
... use entity manager inside a transaction ...
}
JPA www.asta.ir 71
Layering and Transactions
Methods of which layer become transactional?
Presentation Layer
Manager
Why? Service Layer
Manager Layer
DAO Layer
DB
JPA www.asta.ir 72
Exercise on JPA
Implement save method in ContactDAO
Using JPA
Note to Transactions
Add “email” field to ContactEntity
Revise the ContactDAO class
How much effort is needed?!
Compare it with the JDBC approach
Simulate an “account-transfer” method in Manager
Which invokes two dao methods in a transactional method
Test the transactionality! Does it roll-back?
JPA www.asta.ir 73
JPA Queries
Using JPQL
JPA www.asta.ir 74
JPA Queries
JPA supports powerful querying API
Dynamic or statically defined (named queries)
Criteria using JPQL (Java Persistence API Query Language)
SQL-like language
Native SQL support (when required)
Named parameters bound at execution time (no SQL injection)
Pagination and ability to restrict size of result
Single/multiple-entity results, data projections
Bulk update and delete operations on an entity
JPA www.asta.ir 75
JPA Query API
Query instances are obtained from factory methods on
EntityManager, e.g.
Query query = entityManager.createQuery(
"SELECT e from Employee e");
JPA www.asta.ir 78
Dynamic Queries – Example
Use createQuery() factory method at runtime
Pass in the JPQL query string
JPA www.asta.ir 79
JPQL Examples
Query query = em.createQuery("Select e FROM Employee e WHERE e.id = :id");
query.setParameter("id", id);
Employee result2 = (Employee)query.getSingleResult();
JPA www.asta.ir 80
Named Queries
Named queries are once defined and invoked later many times
@NamedQuery(name="Sale.findByCustId",
query="select s from Sale s
where s.customer.id = :custId
order by s.salesDate")
Like expression
SELECT e FROM Employee e WHERE p.name LIKE 'Mich%‘
Parameterized: ... WHERE p.name LIKE :name||'%'
JPA www.asta.ir 83
Mapping Tables to Classes by
Annotations
ORM Mappings
JPA www.asta.ir 84
Object / Relational Mapping
Map persistent object state to relational database
Map relationships between entities
Describe the physical model (DB tables and columns), e.g. @Table
JPA www.asta.ir 85
Simple Mappings
Direct mappings of fields to columns
@Basic – optional, indicates simple mapped attribute
Can specify fetch=EAGER / fetch=LAZY
LAZY: container defers loading until the field or property is accessed
(load on demand)
EAGER: the field or relationship loaded when the referencing entity is loaded
(pre-load)
Maps any of the common simple Java types
Primitives (int, long, String), wrappers, serializable, etc.
Used in conjunction with @Column
Can override any of the defaults
JPA www.asta.ir 86
Simple Mappings (Annotations)
@Entity
public class Customer {
CUSTOMER
@Id
ID NAME CREDIT PHOTO
int id;
@Basic @Column(name="name")
String name;
@Basic @Column(name="CREDIT")
int creditRating;
@Lob
Image photo;
}
JPA www.asta.ir 87
Simple Mappings (XML)
It is also possible to describe mappings by XML files
But we focus on annotation-based mappings
<entity class="model.Customer">
<attributes>
<id name="id" />
<basic name="name" />
<basic name="creditRating">
<column name="CREDIT" />
</basic>
<basic name="photo"><lob /></basic>
</attributes>
</entity>
JPA www.asta.ir 88
Relationship Mappings
Cardinality:
@ManyToOne, @OneToOne – single entity
@OneToMany, @ManyToMany – collection
Direction (navigability):
Unidirectional: we can go from entity A to entity B only.
Bi-directional: we can go from entity A to entity B & vice-versa.
Owning and inverse sides
Owning side specifies the physical mapping
@JoinColumn to specify foreign key DB column
@JoinTable decouples physical relationship mappings from entity tables
JPA www.asta.ir 89
Many-To-One Mapping (Annotations)
@Entity
public class Sale { SALE
@Id ID … CUST_ID
int id;
...
@ManyToOne
@JoinColumn(name="CUST_ID") CUSTOMER
Customer cust; ID …
}
JPA www.asta.ir 90
One-To-Many Mapping (Attributes)
@Entity
public class Customer {
CUSTOMER
@Id ID …
int id;
@OneToMany(mappedBy="cust")
Set<Sale> sales;
}
SALE
@Entity
public class Sale { ID … CUST_ID
@Id
int id;
@ManyToOne
Customer cust;
}
JPA www.asta.ir 91
Many-To-Many Example @Entity
public class Project {
@Entity @Id
public class Employee { @Column(name="ID")
@Id private long id;
@Column(name="ID") ...
private long id; @ManyToMany(mappedBy="projects")
... private List<Employee> employees;
@ManyToMany ...
@JoinTable( }
name="EMP_PROJ",
joinColumns=@JoinColumn(name="EMP_ID", referencedColumnName="ID"),
inverseJoinColumns=@JoinColumn(name="PROJ_ID", referencedColumnName="ID"))
private List<Project> projects;
.....
}
JPA www.asta.ir 92
Bi-directional and Unidirectional Relationships
The relationship may be unidirectional
If one end does not need to use the relationship
Example: Unidirectional ManyToMany relationship:
@Entity 0* 0*
@JoinTable(name = "PROJECT_EMPLOYEE",
joinColumns={@JoinColumn(name="EMPLOYEES_ID", @Entity
referencedColumnName="ID")},inverseJoinColumns public class Project {
={@JoinColumn(name="PROJECTS_ID", @Id
referencedColumnName = "ID")}) private Integer id;
@ManyToMany ...
private List<Project> projectList; }
...
}
JPA www.asta.ir 93
Lazy Collection Fetching
A collection is fetched when the application invokes an
operation upon that collection
This is the default for collections
Fetch Types:
EAGER: Defines that data must be eagerly fetched
Remind:
Properties (basic fields) can also be lazy loaded (But default is eager)
JPA www.asta.ir 94
Lazy Fetching Example
@Entity
public class ProductEntity {
... @ManyToMany(fetch=FetchType.LAZY)
@ManyToMany(fetch=FetchType.EAGER)
private List<CategoryEntity> categories;
}
JPA www.asta.ir 95
Cascade Strategies
Cascading Actions
Cascading of entity operations to related entities
may be defined per relationship
JPA www.asta.ir 97
Persisting Relationships
@Entity
@Table(name = "PHONE")
public class Phone implements Serializable {
...
@ManyToOne(cascade = CascadeType.ALL)
@JoinColumn(name = "EMPLOYEE_ID", referencedColumnName = "ID")
private Employee employee;
}
JPA www.asta.ir 98
Cascade Types:
ALL
Cascade all operations
PERSIST
Cascade persist operation
MERGE
Cascade merge operation
REMOVE
REFRESH
DETACH
JPA www.asta.ir 99
Exercise
Assume the relationships
Order [1-n] Item
Item [n-1] Product
Product [n-n] Category
Define Entities
Add annotations
Set appropriate lazy/eager
Defines Services:
Add product (with a POST request to …/product/save)
With no category
Add Order
Add Item (…/add-item/23/12/3 Create an item: count=3, product_id=12, order-id=23)
JPA www.asta.ir 100
Exercise (cont’d)
Defines Services:
Add-product-item
…/category/categoryname/productname
(Adds a product in a new category)
Does it work with no cascade?
No, results in an exception
Set appropriate Cascade type
@AssertFalse
@AssertFalse The value of the field or property must be false.
boolean isUnsupported;
@AssertTrue
@AssertTrue The value of the field or property must be true.
boolean isActive;
The value of the field or property must be a decimal
@DecimalMax("30.00")
@DecimalMax value lower than or equal to the number in the value
BigDecimal discount;
element.
The value of the field or property must be a decimal
@DecimalMin("5.00")
@DecimalMin value greater than or equal to the number in the value
BigDecimal discount;
element.
@Future
@Future The value of the field or property must be a date in the future.
Date eventDate;
The value of the field or property must be an integer value lower than or @Max(10)
@Max
equal to the number in the value element. int quantity;
The value of the field or property must be an integer value greater than or @Min(5)
@Min
equal to the number in the value element. int quantity;
@NotNull
@NotNull The value of the field or property must not be null.
String username;
@Null
@Null The value of the field or property must be null.
String unusedString;
@Past
@Past The value of the field or property must be a date in the past.
Date birthday;
@Pattern(regexp="\\(\\d{3}\\)\\d
The value of the field or property must match the regular
@Pattern {3}-\\d{4}")
expression defined in the regexp element.
String phoneNumber;
The size of the field or property is evaluated and must match the
specified boundaries. If the field or property is a String, the size of
the string is evaluated. If the field or property is a Collection, the
@Size(min=2, max=240)
@Size size of the Collection is evaluated. If the field or property is a Map,
String briefMessage;
the size of the Map is evaluated. If the field or property is an array,
the size of the array is evaluated. Use one of the optional max or
min elements to specify the boundaries.
}
...
}
Custom constraints
Evaluated automatically
JPA
JPQL may look simpler, but criteria API
www.asta.ir
has its own advantages 126
CriteriaBuilder
A CriteriaBuilder is obtained from an EntityManager
CriteriaBuilder cb = entityManager.getCriteriaBuilder();
CriteriaBuilder is used to construct CriteriaQuery objects and their expressions
CriteriaBuilder API:
createQuery() - Creates a CriteriaQuery
createQuery(Class): using generics to avoid casting the result class
createTupleQuery() - Creates a CriteriaQuery that returns map like Tuple objects
instead of object arrays for multiselect queries
createCriteriaDelete(Class) and createCriteriaUpdate(Class)
Creates a CriteriaDelete or CriteriaUpdate to delete/update a batch of objects (JPA 2.1)
CriteriaBuilder cb = entityManager.getCriteriaBuilder();
JPA
CriteriaQuery<User> cq = cb.createQuery(User.class);
www.asta.ir 127
CriteriaQuery API
(CriteriaQuery defines a database select query)
from(Class) : Defines an element in the query's from clause
At least one from element is required for the query to be valid
groupBy(Expression...), groupBy(List<Expression>)
Defines the query's group by clause
CriteriaQuery<Employee> c = cb.createQuery(Employee.class);
Root<Employee> emp = c.from(Employee.class);
c.select(emp)
.where(cb.equal(emp.get("address").get("city"), "Yazd"));
CriteriaQuery<Employee> c = cb.createQuery(Employee.class);
Root<Employee> emp = c.from(Employee.class);
c.select(emp)
.where(emp.get("address")
.get("state").in("Yazd","Qom"));
CriteriaBuilder cb = em.getCriteriaBuilder();
CriteriaQuery<Phone> query = cb.createQuery(Phone.class);
Root<Teacher> teacher = query.from(Teacher.class);
Join<Teacher, Phone> phones = teacher.join("phones");
query.select(phones).where(cb.equal(teacher.get("firstName"), "Sadegh"));
CriteriaQuery<Employee> c = cb.createQuery(Employee.class);
Root<Employee> emp = c.from(Employee.class);
c.orderBy(cb.desc(emp.get("name")), cb.asc(emp.get("age")));
SELECT e, COUNT(p)
FROM Employee e JOIN e.projects p
GROUP BY e HAVING COUNT(p) >= 2
CriteriaDelete<Employee> q = cb.createCriteriaDelete(Employee.class);
Root<Employee> emp = q.from(Employee.class);
q.where(cb.isNull(emp.get("dept")));
…/min-items/order-id/min-quantity
and a primary key with the same value as the record in the table
of the superclass.
@Entity
@Inheritance(strategy = InheritanceType.JOINED)
public abstract class Publication {
JPA www.asta.ir 150
Choosing a Strategy
1- Mapped Superclass Strategy
2- Table per Class Strategy
3- Single Table Strategy
4- Joined Strategy