
JavaEE workshop #8
Viktor Martiš
(JPA - advance, DTO)
Agenda
- Builder design patern
-
JPA
- Entity lifecycle
- JPQL and criteria API
- Relations
- Fetch type
- Named queries
- DTO and transformations
Design pattern: Builder
- object creation pattern
- solution to the telescoping constructor anti-pattern, that occurs when the increase of object constructor parameter combination leads to an exponential list of constructors
JPA architecture

JPA Architecture
| EntityManagerFactory | This is a factory class of EntityManager. It creates and manages multiple EntityManager instances. |
| EntityManager | It is an Interface, it manages the persistence operations on objects. It works like factory for Query instance. |
| Entity | Entities are the persistence objects, stores as records in the database. |
| EntityTransaction | It has one-to-one relationship with EntityManager. For each EntityManager, operations are maintained by EntityTransaction class. |
| Persistence | This class contain static methods to obtain EntityManagerFactory instance. |
| Query | This interface is implemented by each JPA vendor to obtain relational objects that meet the criteria. |
JPA Entity Lifecycle
- managed vs detached
- entity updates in active transaction are persisted
- lazy loading works only in active transaction

JPA - EntityManager
| find(Class<T> entityClass, Object primaryKey) | Find by primary key. |
| getReference(Class<T> entityClass, Object primaryKey) | Get an instance, whose state may be lazily fetched. |
| persist(Object entity) | Make an instance managed and persistent. |
| merge(T entity) | Merge the state of the given entity into the current persistence context. |
| remove(Object entity) | Remove the entity instance. |
| refresh(Object entity) | Refresh the state of the instance from the database, overwriting changes made to the entity, if any. |
| flush() | Synchronize the persistence context to the underlying database. |
| createQuery(String qlString) | Create an instance of Query for executing a Java Persistence query language statement. |
| createNamedQuery(String name) | Create an instance of Query for executing a named query (in the Java Persistence query language or in native SQL). |
JPA - @MappedSuperclass
- Designates a class whose mapping information is applied to the entities that inherit from it. A mapped superclass has no separate table defined for it.
@MappedSuperclass
public class AbstractEntity {
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id", columnDefinition = "serial")
@Id
private Long id;JPA - Inheritance Strategies
- SINGLE_TABLE
- makes all classes fields (both super and sub classes) and map them down into a single table
- JOINED_TABLE
- share the referenced column which contains unique values to join the table
- TABLE_PER_CONCRETE_CLASS
- create a table for each sub entity. Table will contain null records
@Entity
@Inheritance( strategy = InheritanceType.JOINED)
public class User {
JPA - Relations
- Unidirectional vs bidirectional
- Side owner
- Relation types
- One to One
- One to Many
- Many to One
- Many to Many
JPA - entity Relationships
//unidirectional example
@Entity(name = "Phone")
public static class Phone {
@Id
@GeneratedValue
private Long id;
private String number;
@OneToOne
@JoinColumn(name = "details_id")
private PhoneDetails details;
public Phone() {
}
...JPA - entity Relationships
-
@OneToMany
- If doesn’t have a mirroring @ManyToOne association on the child side, the @OneToMany association is unidirectional. If there is a @ManyToOne association on the child side, the @OneToMany association is bidirectional
- with @JoinColumn hibernate doesn't create database join table.
@Entity
public class Trainer {
@OneToMany
@JoinTable(
name="TrainedMonkeys",
joinColumns = @JoinColumn( name="trainer_id"),
inverseJoinColumns = @JoinColumn( name="monkey_id")
)
public Set<Monkey> getTrainedMonkeys() {
...
}
JPA - entity Relationships
@Entity(name = "Person")
public static class Person {
@Id
@GeneratedValue
private Long id;
public Person() {
}
}
@Entity(name = "Phone")
public static class Phone {
@Id
@GeneratedValue
private Long id;
private String number;
@ManyToOne
@JoinColumn(name = "person_id",
foreignKey = @ForeignKey(name = "PERSON_ID_FK")
)
private Person person;
...
}JPA - entity Relationships
@Entity(name = "Employee")
public static class Employee {
@Id
private Long id;
@Column(name = "pswd")
@ColumnTransformer(
read = "decrypt( 'AES', '00', pswd )",
write = "encrypt('AES', '00', ?)"
)
private String password;
@ManyToMany(mappedBy = "employees")
private List<Project> projects = new ArrayList<>();
...
}
@Entity(name = "Project")
public class Project {
@Id
private Long id;
@ManyToMany
private List<Employee> employees = new ArrayList<>();
...
}JPA - named queries
- @NamedQuery annotation define query with a predefined unchangeable query string
- improve code organization by separating the JPQL query strings from POJO
@Entity
@Table
@NamedQuery(query = "Select e from Employee e where e.eid = :id", name = "find employee by id")
public class Employee {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private int eid;
private String ename;
private double salary;
private String deg;Query query = entitymanager.createNamedQuery("find employee by id");
query.setParameter("id", 1204);
List<Employee> list = query.getResultList( );JPA - Eager vs. Lazy Loading
- Eager fetching - fetching the whole record while finding the record using Primary Key.
- Lazy fetch - It checks for the availability of notifies it with primary key if it exists. Then later if you call any of the getter method of that entity then it fetches the whole.
- Fetch join - enables the fetching of an association as a side effect of the execution of a query
DTO
- Data transfer object
- Represent input and output of exposed API
- Why ?
- security
- clear cut of transaction
- different data representation
- split representation logic from internal domain (entity)
- How ?
- Spring Converter interface
- mapstruct
- ...
- Where ?
- service layer
Q & A
ITA-05-Java W8
By IT-absolvent
ITA-05-Java W8
- 441