9 Eylül 2019 Pazartesi

JPA EntityManager Arayüzü

Giriş
Şu satırı dahil ederiz.
import javax.persistence.EntityManager;
Bu sınıfı EntityManagerFactory tarafından yaratılır. Açıklaması şöyle.
In general you need a single Entity Manager per transaction. And this Entity Manager must not be used in two transactions at the same time.
Bu sınıf @PersistenceContext Anotasyonu tarafından inject edilebilir.

Hibernate bu arayüzü HibernateEntityManager sınıfı ile gerçekleştirir.

Bu sınıf checked exception fırlatmaz. PersistenceException'dan kalıtan bir unchecked exception fırlatır.

Örnek
Şöyle yaparız.
EntityManager em = createEntityManager();

try {

    em.getTransaction().begin();
    // Do something with the EntityManager such as persist(), merge() or remove()
    em.getTransaction().commit();
} catch(Exception e) {

    em.getTransaction().rollback();
}

em.close();
constructor
Şöyle yaparız.
EntityManagerFactory emf = ...;
EntityManager em = emf.createEntityManager();
clear metodu
Persistence Context'i temizlediği için uygulamayı hızlandırabilir.

close metodu
Şöyle yaparız.
em.close();
createNamedQuery metodu
JPQL veya native SQL kullanabilir. Bir Query nesnesi döner. Sorgu cümlesine isim ile erişiriz. Şöyle yaparız.
Query q = em.createNamedQuery("Card.findPrefix");
createNativeQuery metodu
SQL kullanan bir Query nesnesi döner. Şöyle yaparız.
Query q = em.createNativeQuery("select count(*) from your_table_name")
createQuery metodu - CriteriaQuery
createQuery metodu yazısına taşıdım.

createQuery metodu - String
createQuery metodu yazısına taşıdım.

createQuery metodu - String + Class
createQuery metodu yazısına taşıdım.

createStoredProcedureQuery metodu
StoredProcedureQuery nesnesi yaratır.
Örnek
Şöyle yaparız
StoredProcedureQuery sp = em.createStoredProcedureQuery(procName);
detach metodu
Örnek ver

find metodu
EntityManager.find() metodu nesneyi aynı Hibernate'in Session.find() metodunda olduğu gibi hemen yükler. EntityManager.getReference() ise Hibernate'in Session.load() metodunda olduğu gibi hemen yüklemez bir proxy nesnesi döner.

Örnek
Şöyle yaparız.
Foo foo = em.find(Foo.class, fooId);
Örnek
find metodu önce kendi önbelleği (cache) içinde arama yapar. Her EntityManager nesnesinin kendi önbelleği vardır. Bunu görmek için şöyle yaparız. em1 içinde yaratılan nesne önbellekte saklanır. em2 içinde güncellense bile em1'in haberi olmaz. em1 nesneye tekrar erişmek isterse eski bilgisi ile önbellekten getirir.
EntityManagerFactory emf = Persistence.createEntityManagerFactory("test");

// Step 1: create entity
EntityManager em1 = emf.createEntityManager();
em1.getTransaction().begin();
Article article = new Article("article_1");
em1.persist(article);
em1.getTransaction().commit();

// Step 2: update entity
EntityManager em2 = emf.createEntityManager();
em2.getTransaction().begin();
Article articleForUpdate = em2.find(Article.class, 1L);
articleForUpdate.setName("updated article_1");
em2.persist(articleForUpdate);
em2.getTransaction().commit();

// Step 3: read updated entity
em1.getTransaction().begin();
Article updatedArticle = em1.find(Article.class, 1L);
em1.getTransaction().commit();

log.info("updated entity: {}", updatedArticle); // logs stale data

em1.close();
em2.close();
emf.close();

Örnek
find ve getReference farkı şöyle
// will return the persistent instance and never returns an uninitialized instance
em.find(Owner.class, id);

// might return a proxied instance that is initialized on-demand
em.getReference(Owner.class, id);
Benzer mantık Hibernate Session sınıfında da var.
// will return the persistent instance and never returns an uninitialized instance
session.get(Owner.class, id);

// might return a proxied instance that is initialized on-demand
session.load(Owner.class, id);
flush metodu
Şöyle yaparız.
em.flush();
getCriteriaBuilder metodu
Şöyle yaparız.
CriteriaBuilder cb = em.getCriteriaBuilder();
getEntityManagerFactory metodu
EntityManagerFactory nesnesi döner. Şöyle yaparız.
entityManager.getEntityManagerFactory();
getReference metodu
EntityManager.find() metodu nesneyi aynı Hibernate'in Session.find() metodunda olduğu gibi hemen yükler. EntityManager.getReference() ise Hibernate'in Session.load() metodunda olduğu gibi hemen yüklemez bir proxy nesnesi döner. Hibernate'in açıklaması şöyle
getReference() obtains a reference to the entity. The state may or may not be initialized. If the entity is already associated with the current running Session, that reference (loaded or not) is returned. If the entity is not loaded in the current Session and the entity supports proxy generation, an uninitialized proxy is generated and returned, otherwise the entity is loaded from the database and returned.
getTransaction metodu
EntityTransaction nesnesi döner. Şöyle yaparız.
EntityManager em = entityManagerFactory.createEntityManager();
em.getTransaction().begin();

em.persist(...);
em.persist(...);
em.persist(...);

em.getTransaction().commit();
joinTransaction metodu
Açıklaması şöyle
The purpose of entityManager.joinTransaction(); is to notify the persistence context to synchronize itself with the current transaction.
Şöyle yaparız.
em.joinTransaction();
lock metodu

OPTIMISTIC
JPA EntityManager Optimistic Lock yazısına taşıdım.

OPTIMISTIC_FORCE_INCREMENT
JPA EntityManager Optimistic Lock yazısına taşıdım.

PESSIMISTIC_WRITE
JPA EntityManager Pessimistic Lock yazısına taşıdım.

PESSIMISTIC_READ
JPA EntityManager Pessimistic Lock yazısına taşıdım.

PESSIMISTIC_FORCE_INCREMENT 
JPA EntityManager Pessimistic Lock yazısına taşıdım.

merge metodu
Açıklaması şöyle.
When merge()is invoked on a new entity, it behaves similarly to the persist()operation. It adds the entity to the persistence context, but instead of adding the original entity instance, it creates a new copy and manages that instance instead. The copy that is created by the merge()operation is persisted as if the persist()method were invoked on it.
Açıklaması şöyle.
If you use entityManager.merge(itemFromClient) instead, the optimistic locking version would be checked automatically, and "updates from the past" rejected
OneToMany ilişikilerde CascadeType = MERGE ise yeni bir child eklenirse, yeni nesneyi kaydeder ve sonuç olarak döner.
Copy the state of the given object onto the persistent object with the same identifier. If there is no persistent instance currently associated with the session, it will be loaded. Return the persistent instance. If the given instance is unsaved, save a copy of and return it as a newly persistent instance. The given instance does not become associated with the session. This operation cascades to associated instances if the association is mapped withcascade="merge".
persist metodu
@Entity olarak işaretli bir nesnesi veritabanına kaydeder. Şöyle yaparız. Eğer entity veritabanında varsa EntityExistsException fırlatılır. Açıklaması şöyle.
Thrown by the persistence provider when EntityManager.persist(Object) is called and the entity already exists
em.getTransaction().begin();
  Foo foo = new  Foo(...);
  em.persist(k);
em.getTransaction().commit();
refresh metodu
Şöyle yaparız.
SomeEntity someEntity = ...;// this entity was found by entity manager previously

em.refresh(someEntity);
setHint metodu
Örnek
Şöyle yaparız
public List<Country> getAll() {
  List<Country> countries = em.createQuery(
    "SELECT c FROM Country c left join c.authors a "
    + "left join a.posts p left join p.likes l"
    + " order by c.COUNTRY_NAME,a.AUTHOR_NAME,p.POST_NAME,l.AUTHOR_NAME")
  .setHint("eclipselink.left-join-fetch", "c.authors.posts.likes")
  .setHint("eclipselink.read-only", true)
  .getResultList();

  countries.stream().flatMap(c -> c.getAuthors().stream())
    .flatMap(a -> a.getPosts().stream()) // all posts
    .forEach(p -> p.removePostsInFans());

  return countries;
}
Açıklaması şöyle. Burada JPQL ile Likes için Left Join yazılsa bile, Left Join Fetch yapılıyor
By default JPA executes an individual SQL query for each parent object to load its associations. The EclipseLink-specific query hint eclipselink.left-join-fetch triggers fetch joins along the specified path c.authors.posts.likes. Without the hint, 20 additional queries would be needed to load the tiny data.

unwrap metodu
Açıklaması şöyle.
Since version 2.0, JPA provides easy access to the APIs of the underlying implementations. EntityManager and EntityManagerFactory provide an unwrap method, which returns the corresponding classes of the JPA implementation. In Hibernate’s case, Session and SessionFactory give you full access to proprietary Hibernate features, such as the support for Streams and Optional.
Şu satırı dahil ederiz.
import org.hibernate.Session;
Şöyle yaparız.
Session session = em.unwrap(Session.class);



Hiç yorum yok:

Yorum Gönder