JavaEE workshop #6 

Kuba Hejda

(flyway, JPA - advance, DTO)

Agenda

  • Flyway
  • 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

Flyway

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
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

JPA - entity Relationships 

  • @OneToOne - unidirectional or bidirectional. A unidirectional association follows the relational database foreign key semantics, the client-side owning the relationship. A bidirectional association features a mappedBy @OneToOne parent side too.
//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 

  • @ManyToMany
    • requires a link table that joins two entities. Can be a either unidirectional or bidirectional.
    • the link table is controlled by the owning side
@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 ?
  • Where ?
    • service layer

Q & A

ITA 05 - W06

By IT-absolvent

ITA 05 - W06

Workshop #6

  • 548