JPA - Beyond copy-paste

42
@jkubrynski / kubrynski.com JPA - BEYOND COPY-PASTE JAKUB KUBRYNSKI [email protected] / @jkubrynski / http://kubrynski.com

Transcript of JPA - Beyond copy-paste

Page 1: JPA - Beyond copy-paste

@jkubrynski / kubrynski.com

JPA - BEYOND COPY-PASTEJAKUB KUBRYNSKI

[email protected] / @jkubrynski / http://kubrynski.com

Page 2: JPA - Beyond copy-paste

WHOAMICO-FOUNDER OF DEVSKILLER / CODEARTE

TRAINER AT BOTTEGA

DEVOXX.PL PROGRAM COMMITTEE

FORMER CONFITURA.PL

Page 3: JPA - Beyond copy-paste
Page 4: JPA - Beyond copy-paste

@Entitypublic class Product

@Id @GeneratedValue private Long id;

@Column private String name;

// ...

Page 5: JPA - Beyond copy-paste

@Entitypublic class Product

@Id @GeneratedValue private Long id;

@Column // it does exactly nothing private String name;

// ...

Page 6: JPA - Beyond copy-paste

@Transactional @Service public class ProductService

public void updatePrice(Long productId, Money newPrice) Product product = productRepository.find(productId); product.setPrice(newPrice); productRepository.save(product);

Page 7: JPA - Beyond copy-paste

@Transactional @Service public class ProductService

public void updatePrice(Long productId, Money newPrice) Product product = productRepository.find(productId); product.setPrice(newPrice); productRepository.save(product); // it does exactly nothing

Page 8: JPA - Beyond copy-paste

FIELDS VS GETTERS@Entitypublic class Product

private Long id;

private String name;

@Id public Long getId() return id;

Page 9: JPA - Beyond copy-paste

MIXED ACCESS@Entity@Access(AccessType.FIELD) public class Product

private Long id;

private String name;

@Id @Access(AccessType.PROPERTY) public Long getId() return id;

Page 10: JPA - Beyond copy-paste

@Entitypublic class Order

Page 11: JPA - Beyond copy-paste

@Entity(name = "orders") public class Order

Page 12: JPA - Beyond copy-paste

@Entity(name = "orders") public class Order

insert into orders ...

Page 13: JPA - Beyond copy-paste

@Entity(name = "orders") public class Order

em.createQuery("SELECT o FROM Order o")

Page 14: JPA - Beyond copy-paste

@Entity(name = "orders") public class Order

em.createQuery("SELECT o FROM orders o")

Page 15: JPA - Beyond copy-paste

@Entity@Table(name = "orders") public class Order

Page 16: JPA - Beyond copy-paste

ONE TO ONE@Entitypublic class Customer

@OneToOne private Address address;

@Entitypublic class Address

@OneToOne private Customer customer;

Page 17: JPA - Beyond copy-paste

ONE TO ONE@Entitypublic class Customer

@OneToOne private Address address;

@Entitypublic class Address

@OneToOne(mappedBy = "address") private Customer customer;

Page 18: JPA - Beyond copy-paste

ONE TO MANY@Entitypublic class Customer

@OneToMany private Set<Address> addresses;

Page 19: JPA - Beyond copy-paste

ONE TO MANY@Entitypublic class Customer

@OneToMany @JoinColumn(name = "customer_id") private Set<Address> addresses;

Page 20: JPA - Beyond copy-paste

MANY TO MANY@Entitypublic class Customer

@ManyToMany private Collection<Address> addresses;

@Entitypublic class Address

@ManyToMany private Collection<Customer> customers;

Page 21: JPA - Beyond copy-paste

LAZY LOADINGelement is loaded only when requiredproxy by subclassing, but not always needed

Page 22: JPA - Beyond copy-paste

LAZY LOADINGCustom collections

PersistentSetPersistentBagPersistentList

Page 23: JPA - Beyond copy-paste

SET, BAG OR LIST?@OneToMany Set<Product> products;

Page 24: JPA - Beyond copy-paste

SET, BAG OR LIST?@OneToMany List<Product> products;

Page 25: JPA - Beyond copy-paste

SET, BAG OR LIST?@OneToMany @OrderColumn List<Product> products;

Page 26: JPA - Beyond copy-paste

N+1@Entitypublic class User

@OneToMany private List<Address> addresses;

List<User> users = em.createQuery("SELECT u FROM User u").getResultList();

for (User user : users) for (Address address : user.getAddresses()) ...

Page 27: JPA - Beyond copy-paste

N+1@Entitypublic class User

@OneToMany @BatchSize(size = 10) private List<Address> addresses;

Page 28: JPA - Beyond copy-paste

N+1SELECT DISTINCT u FROM User u JOIN FETCH u.addresses

Page 29: JPA - Beyond copy-paste

HOW TO SAVEEntityManager.persist()EntityManager.merge()

Page 30: JPA - Beyond copy-paste

OPTIMISTIC LOCKING@Entitypublic class User

@Version private int version;

Page 31: JPA - Beyond copy-paste

OPTIMISTIC LOCKING IN RESTNEVER HEARD OF IT

Page 32: JPA - Beyond copy-paste

IDENTITYEQUALS() AND HASHCODE()

Page 33: JPA - Beyond copy-paste

BASE CLASS@MappedSuperclass public abstract class BaseEntity implements Serializable

@Id @GeneratedValue private Long id;

private String uuid = UUID.randomUUID().toString();

public int hashCode() return Objects.hash(uuid);

public boolean equals(Object that) return this == that || that instanceof BaseEntity && Objects.equals(uuid, ((BaseEntity) that).uuid);

Page 34: JPA - Beyond copy-paste

CACHINGL1 - EntityManager cache / Session cacheL2 - EntityManagerFactory cache / SessionFactory cacheQueryCache

Page 35: JPA - Beyond copy-paste

FLUSH MODESMANUALCOMMITAUTOALWAYS

Page 36: JPA - Beyond copy-paste

LEVEL 1 CACHE PITFALLSFLUSH() AND CLEAR()

Page 37: JPA - Beyond copy-paste

LEVEL 2 CACHE PITFALLSDISTRIBUTED ENVIRONMENT

Page 38: JPA - Beyond copy-paste

HQL INJECTIONString hqlQuery = "SELECT p FROM Product p where p.category = '" + cat + "'";

List<Product> products = em.createQuery(hqlQuery, Product.class) .getResultList();

Page 39: JPA - Beyond copy-paste

DYNAMIC UPDATES@Entity@DynamicUpdate public class MyEntity // ...

Page 40: JPA - Beyond copy-paste

DYNAMIC INSERTS@Entity@DynamicInsert public class MyEntity // ...

Page 41: JPA - Beyond copy-paste

QUESTIONS?

Page 42: JPA - Beyond copy-paste

THANKS