Giriş
Şu satırı dahil ederiz.
Spring ile kullanıyorsak bir tane proxy inject edilir. Açıklaması şöyle. Her transaction için farklı bir EntityManager daha doğrusu Hibernate Session nesnesi kullanılır.
Spring ile şöyle yaparız.
Spring ile şöyle yaparız.
persistence.xml dosyasındaki isim ile aynı olmalıdır.
Örnek
Elimizde şöyle bir XML olsun.
Açıklaması şöyle. Her transaction için aynı EntityManager daha doğrusu Hibernate Session nesnesi kullanılır.
Şu satırı dahil ederiz.
import javax.persistence.PersistenceContext;
Java EE dünyasında container tarafından yönetilen bir EntityManager nesnesidir.Spring ile kullanıyorsak bir tane proxy inject edilir. Açıklaması şöyle. Her transaction için farklı bir EntityManager daha doğrusu Hibernate Session nesnesi kullanılır.
Proxied entity manager for @PersistenceContextFarklı olmasının açıklaması şöyle
Thanks to this transaction-aware proxies, EntityManager injected as @PersistenceContext can be used as a thread-safe object. It means that each requests will be handled by its own EntityManager. Why EntityManager is used through a proxy ? By definition (JSR-317 Final Release, section "7.3 Obtaining an Entity Manager Factory"), EntityManager is not thread safe. But according to the Spring's documentation, EntityManager injected through @PersistenceContext is "thread-safe proxy for the actual transactional EntityManager".
You shouldn't use @Autowired. @PersistenceContext takes care to create a unique EntityManager for every thread. In a production application you can have multiple clients calling your application in the same time. For each call, the application creates a thread. Each thread should use its own EntityManager. Imagine what would happen if they share the same EntityManager: different users would access the same entities.Bu proxy kodla transaction yaratılmasına izin vermez. Eğer denersek şöyle bir exception alırız
java.lang.IllegalStateException: Not allowed to create transaction on shared EntityManager - use Spring transactions or EJB CMT insteadBu PersistenceContext.EXTENDED halini kullanırsak da kodla transaction yaratılmasına izin vermez. Eğer denersek şöyle bir exception alırız
java.lang.IllegalStateException: Cannot obtain local EntityTransaction from a transaction-synchronized EntityManagerÖrnek
Spring ile şöyle yaparız.
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;
import javax.transaction.Transactional;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Repository;
@Transactional
@Repository
public class PasswordJpaDaoImpl implements PasswordJpaDaoCustom {
@PersistenceContext
private EntityManager em;
...
}
ÖrnekSpring ile şöyle yaparız.
public interface CustomerRepositoryCustom {
List<Customer> getByCompany(Long id, int page, int size);
}
@Transactional(readOnly = true)
public class CustomerRepositoryImpl implements CustomerRepositoryCustom {
@PersistenceContext
private EntityManager entityManager;
public List<Customer> getByCompany(Long id, int page, int size) {
...
}
}
unitName Alanıpersistence.xml dosyasındaki isim ile aynı olmalıdır.
Örnek
Elimizde şöyle bir XML olsun.
<persistence xmlns="http://java.sun.com/xml/ns/persistence"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/persistence
http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd"
version="2.0">
<persistence-unit name="manager1" transaction-type="RESOURCE_LOCAL">
<provider>org.hibernate.ejb.HibernatePersistence</provider>
<properties>
<property name="javax.persistence.jdbc.driver"
value="com.mysql.jdbc.Driver"/>
<property name="javax.persistence.jdbc.user" value="root"/>
<property name="javax.persistence.jdbc.password" value="mypassword"/>
<property name="javax.persistence.jdbc.url"
value="jdbc:mysql://localhost/ptbrowserdb"/>
<property name="hibernate.dialect"
value="org.hibernate.dialect.MySQLDialect"/>
</properties>
</persistence-unit>
</persistence>
Şöyle yaparız.@PersistenceContext(unitName = "manager1")
private EntityManager entityManager;
type AlanıAçıklaması şöyle. Her transaction için aynı EntityManager daha doğrusu Hibernate Session nesnesi kullanılır.
Notice that you can inject an no thread-safe persistence context by using type="PersistenceContextType.EXTENDED" attribute in @PersistenceContext annotation.
Hiç yorum yok:
Yorum Gönder