Skip to content

Latest commit

 

History

History
541 lines (401 loc) · 10 KB

slide1.md

File metadata and controls

541 lines (401 loc) · 10 KB

JPA

Quick intro/Crash course

Part 1


About me

  • student
  • not even an intern
  • JVM enthusiast

What is JPA?

The Java Persistence API is a specification for:

  • accessing
  • persisting
  • and managing

data between Java objects / classes and a relational database


Why JPA?

JPA is now considered the standard industry approach for Object to Relational Mapping (ORM) in the Java Industry.


But wait...

JPA itself is just a specification, not a product. It cannot perform persistence or anything else by itself. JPA is just a set of interfaces and requires an implementation


Provider

A provider is needed. There are several:

  • Hibernate
  • EclipseLink
  • OpenJPA

Hibernate is used in more than 70% of projects

Use Gradle or Maven, it's that simple


All we need is a single file

persistence.xml

assuming you already have your database set up...


Persistence.xml

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<persistence ... version="2.1">
  <persistence-unit name="h2" transaction-type="RESOURCE_LOCAL">
    <provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>
      <properties>
        <property name="javax.persistence.jdbc.driver"
        value="org.h2.Driver"/>
        <property name="javax.persistence.jdbc.url"
        value="jdbc:h2:mem:testdb"/>
        <property name="hibernate.dialect"
        value="org.hibernate.dialect.H2Dialect"/>
        <property name="hibernate.hbm2ddl.auto" 
        value="update"/>
      </properties>
  </persistence-unit>
</persistence>

POJO

public class Author {

	private String firstName;
	private String lastName;

	// Constructors, getters and setters..

Note: Konwencja JavaBean


Entity

@Entity 
public class Author {

	@Id 
	@GeneratedValue(strategy = GenerationType.AUTO)
	private Long id;

	private String firstName;
	private String lastName;

	public Author() {
	}
	// Constructors, getters and setters..
Hibernate:
create table Author(
	id bigint generated by default as identity,
	firstName varchar(255),
	lastName varchar(255),
	primary key (id)
)

Note: W pełni funkcjonująca encja, wymagane są: @Entity, @Id oraz konstruktor bezargumentowy


Detached Entity and Managed Entity

lifecycle


Annotations

@Entity 
@Table(name = "Authors")
public class Author {
	
	//Id

	@Column(name = "last_name", 
		nullable = true, 
		unique = false, 
		insertable = true, 
		updatable = true, 
		length = 255)
	private String lastName;

	// Constructors, getters and setters..

Note: @Table -> nazwa tabeli nie encji


Field vs getter

@Column(name = "SAMPLE_STRING")  
private String sampleString;

public String getSampleString(){  
  return sampleString;  
}

vs

private String sampleString;

@Column(name = "SAMPLE_STRING")  
public String getSampleString(){  
  return sampleString;  
}  

Note: używać tylko jednego bo się krzaczy @Access


Time types in entity - Default

@Entity 
public class Event {

	// Id
	private Date date;
	// Constructors, getters and setters..
Hibernate: 
create table Events (
	id bigint not null,
	eventDate timestamp,
	event_name varchar(255),
	primary key (id)
)

2018-12-05 12:37:27.955000000


Time types in entity - Time

@Entity
public class Event {

	// Id
	@Temporal(TemporalType.TIME)
	private Date date;
	// Constructors, getters and setters..
Hibernate:
create table Events (
	id bigint not null, 
	eventDate time, 
	event_name varchar(255),
	primary key (id)
)

12:43:23

Note: Zmiany dokonują się na poziomie bazy danych Zmiana w kodzie z DATE na TIME bez zmiany w bazie skutkowała pojawieniem się w bazie: 1970-01-01


Time types in entity - Timestamp

@Entity
public class Event {
	// Id
	@Temporal(TemporalType.TIMESTAMP)
	private Date date;
	// Constructors, getters and setters..
Hibernate:
create table Events (
	id bigint not null, 
	eventDate timestamp,
	event_name varchar(255),
	primary key (id)
)

2018-12-05 13:05:28.530000000


Time types in entity - Date

@Entity
public class Event {

	// Id
	@Temporal(TemporalType.DATE)
	private Date date;
	// Constructors, getters and setters..
Hibernate:
create table Events (
	id bigint not null, 
	eventDate date,
	event_name varchar(255),
	primary key (id)
)

2018-12-05


Transient

@Entity 
public class Author {

	// Id
	private String firstName;
	private String lastName;

	@Transient
	private int age;

	// Constructors, getters and setters..
Hibernate: 
insert into
Author (id, first_name, last_name)
values (null, ?, ?)

Persistence classes

EntityManagerFactory factory = 
	Persistence.createEntityManagerFactory("h2");
EntityManager manager = factory.createEntityManager();
EntityTransaction transaction = manager.getTransaction();

Persist entity

Author author = new Author("Tom", "Clancy");
transaction.begin();
manager.persist(author);
transaction.commit();

Find entity

Long authorId = 1L;
Author author = manager.find(Author.class, authorId);
System.out.println(author.getFirstName());

but something's wrong...

author can be null!


Update entity using merge

transaction.begin();
Author author = new Author("Tom", "Clancy");
manager.persist(author);
transaction.commit();

Author authorToBeFound = new Author();
authorToBeFound.setId(1L);
authorToBeFound.setFirstName("Arnold");
authorToBeFound.setLastName("Schwarzenegger");

transaction.begin();
Author found = manager.merge(authorToBeFound);
transaction.commit();

Update entity using merge - generated SQL

Hibernate: 
insert into Author (id, first_name, last_name)
	values (null, ?, ?)

Author{id=1, firstName='Tom', lastName='Clancy'}

Hibernate:
update Author 
	set 
		first_name=?,
		last_name=?
where id=?

Author{id=1, firstName='Arnold', lastName='Schwarzenegger'}

Update entity using update

Long authorId = 1L;
author = manager.find(Author.class, authorId);

transaction.begin();
author.setId(1L);
author.setFirstName("Arnold");
author.setLastName("Schwarzenegger");
transaction.commit();

Update entity using update - generated SQL

Exaclty the same!


Remove entity

Optional.ofNullable(manager.find(Author.class, authorId))
	.ifPresent(found -> {
	transaction.begin();
	manager.remove(found);
	transaction.commit();
});

Remove entity using merge

Author toBeRemoved = new Author();
toBeRemoved.setId(1L);
transaction.begin();
manager.remove(manager.merge(toBeRemoved));
transaction.commit();

Queries

  • Query
  • NativeQuery
  • NamedQuery
  • TypedQuery
  • CriteriaQuery

Simple select

Query query = manager.createQuery("SELECT e FROM Event e");
List<Event> fromQuery = (List<Event>) query.getResultList();
fromQuery.forEach(System.out::println);

Unchecked cast: 'java.util.List' to 'java.util.List<com.test.model.Event>'


Single result by id - ordinal parameter

Query query = manager
.createQuery("SELECT e FROM Event e WHERE e.id=?1");

query.setParameter(1, 1L);

Event fromQuery = (Event) query.getSingleResult();
System.out.println(fromQuery);

Single result by id - named parameter

Query query = manager
.createQuery("SELECT e FROM Event e WHERE e.id=:id");

query.setParameter("id", 1L);

Event eventFromDatabase = (Event) query.getSingleResult();
System.out.println(eventFromDatabase);

Casting is bad - TypedQuery<?>

TypedQuery<Event> query = manager
.createQuery(
	"SELECT e FROM Event e WHERE e.id=:id",
	Event.class);

query.setParameter("id", 1L);
Event eventFromDatabase = query.getSingleResult();
System.out.println(eventFromDatabase);

TypedQuery<?>

TypedQuery<Event> query = manager
.createQuery("SELECT e FROM Event e", Event.class);

List<Event> eventsFromDatabase = query.getResultList();
eventsFromDatabase.forEach(System.out::println);

That's all for today


Next presentation:

  • Queries
  • Relationships
  • Inheritance
  • Callback Annotations
  • EventListeners