JPA - Beyond copy-paste
-
Upload
jakub-kubrynski -
Category
Software
-
view
746 -
download
1
Transcript of JPA - Beyond copy-paste
@jkubrynski / kubrynski.com
JPA - BEYOND COPY-PASTEJAKUB KUBRYNSKI
[email protected] / @jkubrynski / http://kubrynski.com
WHOAMICO-FOUNDER OF DEVSKILLER / CODEARTE
TRAINER AT BOTTEGA
DEVOXX.PL PROGRAM COMMITTEE
FORMER CONFITURA.PL
@Entitypublic class Product
@Id @GeneratedValue private Long id;
@Column private String name;
// ...
@Entitypublic class Product
@Id @GeneratedValue private Long id;
@Column // it does exactly nothing private String name;
// ...
@Transactional @Service public class ProductService
public void updatePrice(Long productId, Money newPrice) Product product = productRepository.find(productId); product.setPrice(newPrice); productRepository.save(product);
@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
FIELDS VS GETTERS@Entitypublic class Product
private Long id;
private String name;
@Id public Long getId() return id;
MIXED ACCESS@Entity@Access(AccessType.FIELD) public class Product
private Long id;
private String name;
@Id @Access(AccessType.PROPERTY) public Long getId() return id;
@Entitypublic class Order
@Entity(name = "orders") public class Order
@Entity(name = "orders") public class Order
insert into orders ...
@Entity(name = "orders") public class Order
em.createQuery("SELECT o FROM Order o")
@Entity(name = "orders") public class Order
em.createQuery("SELECT o FROM orders o")
@Entity@Table(name = "orders") public class Order
ONE TO ONE@Entitypublic class Customer
@OneToOne private Address address;
@Entitypublic class Address
@OneToOne private Customer customer;
ONE TO ONE@Entitypublic class Customer
@OneToOne private Address address;
@Entitypublic class Address
@OneToOne(mappedBy = "address") private Customer customer;
ONE TO MANY@Entitypublic class Customer
@OneToMany private Set<Address> addresses;
ONE TO MANY@Entitypublic class Customer
@OneToMany @JoinColumn(name = "customer_id") private Set<Address> addresses;
MANY TO MANY@Entitypublic class Customer
@ManyToMany private Collection<Address> addresses;
@Entitypublic class Address
@ManyToMany private Collection<Customer> customers;
LAZY LOADINGelement is loaded only when requiredproxy by subclassing, but not always needed
LAZY LOADINGCustom collections
PersistentSetPersistentBagPersistentList
SET, BAG OR LIST?@OneToMany Set<Product> products;
SET, BAG OR LIST?@OneToMany List<Product> products;
SET, BAG OR LIST?@OneToMany @OrderColumn List<Product> products;
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()) ...
N+1@Entitypublic class User
@OneToMany @BatchSize(size = 10) private List<Address> addresses;
N+1SELECT DISTINCT u FROM User u JOIN FETCH u.addresses
HOW TO SAVEEntityManager.persist()EntityManager.merge()
OPTIMISTIC LOCKING@Entitypublic class User
@Version private int version;
OPTIMISTIC LOCKING IN RESTNEVER HEARD OF IT
IDENTITYEQUALS() AND HASHCODE()
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);
CACHINGL1 - EntityManager cache / Session cacheL2 - EntityManagerFactory cache / SessionFactory cacheQueryCache
FLUSH MODESMANUALCOMMITAUTOALWAYS
LEVEL 1 CACHE PITFALLSFLUSH() AND CLEAR()
LEVEL 2 CACHE PITFALLSDISTRIBUTED ENVIRONMENT
HQL INJECTIONString hqlQuery = "SELECT p FROM Product p where p.category = '" + cat + "'";
List<Product> products = em.createQuery(hqlQuery, Product.class) .getResultList();
DYNAMIC UPDATES@Entity@DynamicUpdate public class MyEntity // ...
DYNAMIC INSERTS@Entity@DynamicInsert public class MyEntity // ...
QUESTIONS?
THANKS