0% found this document useful (0 votes)
480 views

Jpa (Java Persistence Api) Cheat Sheet: Transaction Management With Entitymanager

This document provides a summary of key concepts in Java Persistence API (JPA) including transaction management, entity life cycle, mappings, queries, inheritance strategies, and more. It discusses using the EntityManager interface to begin and commit transactions when persisting, updating, and deleting entities. It also covers the different states an entity can be in, the various mapping associations in JPA, and how to perform queries using JDBC, JPQL, native SQL, and criteria queries.

Uploaded by

Karthik Baskaran
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
480 views

Jpa (Java Persistence Api) Cheat Sheet: Transaction Management With Entitymanager

This document provides a summary of key concepts in Java Persistence API (JPA) including transaction management, entity life cycle, mappings, queries, inheritance strategies, and more. It discusses using the EntityManager interface to begin and commit transactions when persisting, updating, and deleting entities. It also covers the different states an entity can be in, the various mapping associations in JPA, and how to perform queries using JDBC, JPQL, native SQL, and criteria queries.

Uploaded by

Karthik Baskaran
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
You are on page 1/ 8

JPA (Java Persistence API) Cheat Sheet

Transaction management with EntityManager


Note: EntityManager is an Interface to the Persistence Context

entityManager.getTransaction().begin();
Person p = new Person();
p.setLastName("Kondayil");
p.setFirstName("Vinod");
entityManager.persist(p);
entityManager.getTransaction().commit();

Eager vs Lazy
@OneToOne and @ManyToOne fetch type is EAGER by default @OneToMany and
ManyToMany fetch type is LAZY by deafult

Entity Life Cycle


Entity life cycle consists of four states: New, Managed, Removed and Detached.

1. New: When an entity object is initially created its state is New. In this state the
object is not yet associated with an EntityManager and has no representation
in the database.
2. Managed: An entity object becomes Managed when it is persisted to the
database via an EntityManager’s persist method. Entity objects retrieved from
the database by an EntityManager are also in the Managed state.
3. Removed: A managed entity object can also be retrieved from the database
and marked for deletion, using the EntityManager’s remove() method within
an active transaction. The entity object changes its state from Managed to
Removed, and is physically deleted from the database during commit.
4. Detached: represents entity objects that have been disconnected from the
EntityManager.

Mappings
Delete dependent children, when the parent is deleted Note: Add mappedBy to the
non-owning side of the relationship to get a biderectional navigation

@OneToMany(mappedBy="blogpost", orphanRemoval=true)
private List<Comment> comments;
Setting fetch time to lazy so that the passport is only selected when it is needed

@Entity
public class Student {
@OneToOne(fetch=FetchType.LAZY)
private Passport passport;
}

Initialize DB
Initialize schema in a Spring Boot App src/main/resources/schema.sql

Populate DB with data in a Spring Boot App src/main/resources/data.sql

Query data using

 JDBC - Plain SQL statements


 JPQL - Query language based on Enitity names (not on table names)
 Criteria Query - Build a query with a Java based API
 Native Query - Plain SQL statements

1. JDBC Selecting all courses from the db Note: BeanPropertyRowMappermaps


all the columns to a Java Pojo

List<Course> courses = jdbcTemplate.query("select * from course", new


BeanPropertyRowMapper<Course>(Course.class));
Selecting a single course

Course course = jdbcTemplate.queryForObject("select * from course where id=?", new


Object[] { 12 }, new BeanPropertyRowMapper<Course>(Course.class));
Updating a single course int rowsAffected = jdbcTemplate.update("update course set
name=? where id=?", new Object[] { "JPA Hibernate", 12 });

2. JPQL

TypedQuery<Course> typedQuery = entityManager.createQuery("select c from Course


c", Course.class);
List<Course> courses = typedQuery.getResultList();
Using Named Queries

TypedQuery<Course> namedQuery = entityManager.createNamedQuery("find_all_courses",


Course.class);
List<Course> courses = namedQuery.getResultList();

@Entity
@NamedQuery(name="find_all_courses", query="select c from Course c")
public class Course {
...
}
Defining multiple named queries

@Entity
@NamedQueries(
value={
@NamedQuery(name="find_all_courses", query="select c from Course c"),
@NamedQuery(name="find_all_courses_starting_with_a", query="select c from
Course c where name like 'a%'")
}
)
public class Course {
...
}

3. Native SQL Queries

Query nativeQuery = em.createNativeQuery("SELECT * FROM course", Course.class);


List<Course> courses = nativeQuery.getResultList();
with parameters (using positions)

Query nativeQuery = em.createNativeQuery("SELECT * FROM course WHERE id = ?",


Course.class);
nativeQuery.setParameter(1, 1023);
List<Course> courses = nativeQuery.getResultList();
with named parameters

Query nativeQuery = em.createNativeQuery("SELECT * FROM course WHERE id = :id",


Course.class);
nativeQuery.setParameter("id", 1023);
List<Course> courses = nativeQuery.getResultList();
updates

Query nativeQuery = em.createNativeQuery("UPDATE course set


last_updated_date=sysdate()");
int rowsAffected = nativeQuery.executeUpdate();

Enabling Transaction Management


When we use @Transactional every set method results in an update of the row
merge method. The changes are flushed to the db at the end of the function.

@Transactional
public void addCourse() {
Course course = new Course("JPA Hibernate");
em.persist(course);
course.setName("JPA and Hibernate");
}//here at this point the INSERT happens to the DB and after that the transaction
commits
Using flush() you can send out changes to the DB within a Transaction

@Transactional
public void foo() {
Course course = new Course("JPA Hibernate");
em.persist(course);
em.flush();

course.setName("JPA and Hibernate");


em.flush();
course.setName("JPA & Hibernate");
em.flush();
}
Using detach() we can prevent changes made to an Entity from going into the DB
within an Transaction

@Transactional
public void foo() {
Course course = new Course("JPA Hibernate");
em.persist(course);
em.flush();

course.setName("JPA and Hibernate");


em.flush();

em.detach(course); //changes to the course entity will not be tracked from here

course.setName("JPA & Hibernate"); //will not be updated since course entity is


detached
}
Using clear() we can prevent changes made to all the entites from going into the DB
within a Transaction

@Transactional
public void foo() {
Course course = new Course("JPA");
em.persist(course);

Course course2 = new Course("Hibernate");


em.persist(course2);

em.flush();
em.clear(); //from this point onwards no changes to the course and course2 will
be reflected

course.setName("JPA Hibernate");
em.flush();

course2.setName("JPA and Hibernate");


em.flush();
}
Using refresh() we get the fresh copy of the values from the DB

@Transactional
public void foo() {
Course course = new Course("JPA");
em.persist(course);
em.flush();

course.setName("Hibernate");

em.refresh(course); //Here the course name will be again refreshed to JPA


em.flush();
}
@Table attributes
@Table annotation provides four attributes, allowing you to override the name of the
table, its catalogue, and its schema, and enforce unique constraints on columns in
the table. @Table( name="fullname", uniqueConstraints =
{@UniqueConstraint(columnNames={"month", "day"})}, //@Column.unique is
recommended )

Embedded Objects
We can declare an embedded component inside an entity. Using embedded objects
student table will be populated with the columns of the address also.

@Embeddable
public class Address {
String line1;
String line2;
String city;
String district;
String state;
String pincode;
}

@Entity
public class Student{
...
@Embedded
private Address address
}

@Column attributes
@Column(
name="fullname", // Name of the table column - default: fieldname
nullable=false, // Is the column nullable - default: true
unique=true, // Is the value of this column unique across the table - default:
false
insertable=false, // Should this field be included in an INSERT command -
default: true
updateable=false, // Should this field be included in an UPDATE command -
default: true
length=20 // Maximum number of chars (only relevant to string fields) - default:
255
)

Hibernate specific annotations


Automatically insert a timestamp when an entity was created (Hibernate specific)

@CreationTimestamp
private LocalDateTime createdDate;
Automatically insert a timestamp when an entity was updated (Hibernate specific)

@UpdateTimestamp
private LocalDateTime lastUpdatedDate;

Inheritance Hierarchies and Strategies


Employee --> id,name FullTimeEmployee --> salary PartTimeEmployee -->
hourlyWage

1. SINGLE_TABLE : we will get a single table for all the above three entities with
a DTYPE column (distinguisher type). Problem with this strategy is that data
integrity is not good. Because columns would have to be nullable.

@Entity
@Inheritance(strategy=InheritanceType.SINGLE_TABLE)
public abstract class Employee{
...
}

----------------------------------------------------
DTYPE | ID | NAME | HOURLY_WAGE | SALARY
----------------------------------------------------
FullTimeEmployee | 1 | ABC | NULL | 1000
----------------------------------------------------
PartTimeEmployee | 2 | XYZ | 25 | NULL
----------------------------------------------------
To change the DTYPE

@DiscriminatorColumn(name="EmployeeType")

2. TABLE_PER_CLASS: a table per concrete class entity will be created. Hence


table will be created for FullTimeEmployee and PartTimeEmployee. The
columns of the employee table will be available in both the concrete class.
When we retreive the rows all of the employees hibernate does the union of
the tables. Demerit: is based on the design such that the common columns are
repeated.

FullTimeEmployee
----------------------
ID | NAME | SALARY
----------------------
1 | ABC | 1000
----------------------

PartTimeEmployee
-------------------------
ID | NAME | HOURLY_WAGE
-------------------------
1 | XYZ | 25
-------------------------
3. JOINED: Fields specific to a subclass are mapped to a separate table. The
common fields of the employee class will be in another table. To retrieve full
employees we need to do the join of three tables. This is the recommended
structure. Demerit: Joining the table to retrieve the data.

Employee
------------
ID | NAME
------------
1 | ABC
------------
2 | XYZ
------------

FullTimeEmployee
--------------------
ID | SALARY
--------------------
1 | 1000
--------------------

PartTimeEmployee
--------------------
ID | HOURLY_WAGE
--------------------
2 | 25
--------------------

4. @MappedSuperClass: Employee is just a superclass for the sake of mapping


fields to its subclasses. No table will exists for a mapped superclass, hence no
need to add @Entity in the Employee class.
Here we cannot retrieve all the employee details just by writing a JPQL or a
native query SELECT * FROM EMPLOYEE, because EMPLOYEE is not an entity.
Hence we need to retrieve all Parttime employees and Fulltime employees and
do the join ourselves. Demerit: separate query to be written to return all the
employees

@MappedSuperClass
public abstract class Employee{
...
}
FullTimeEmployee
----------------------
ID | NAME | SALARY
----------------------
1 | ABC | 1000
----------------------

PartTimeEmployee
-------------------------
ID | NAME | HOURLY_WAGE
-------------------------
1 | XYZ | 25
-------------------------

You might also like