Spring'da JPA spetsifikatsiyasi, org.springframework.orm.jpa paketida mavjud, Java Persistence APIni qo'llab-quvvatlaydi, Hibernate bilan integratsiya qilingani kabi, qo'shimcha imkoniyatlar taqdim etish uchun bazaviy rejalashtirishni hisobga olib.
Spring'da JPA sozlashning uch xil varianti
Spring'da JPA'ni qo'llab-quvvatlash EntityManagerFactory'ni JPA'dan olishning uch usulini taklif qiladi, bu dastur uchun ma'lumotlar menejeri olish uchun ishlatiladi.
-
LocalEntityManagerFactoryBeandan foydalanish -
EntityManagerFactory'niJNDIdan olish -
LocalContainerEntityManagerFactoryBeandan foydalanish
LocalEntityManagerFactoryBean dan foydalanish
Bu variantni faqatgina oddiy deployment muhiti, masalan, standalone dasturni yurgazish va integratsiya testlarida foydalanish mumkin.
LocalEntityManagerFactoryBean oddiy deployment muhitlari uchun ma'qul bo'lgan EntityManagerFactory ishlab chiqaradi, bu yerda dastur faqat JPA orqali ma'lumotlarga kirishmoqda. Bean-fabrika JPA'dan (Java SE'da JPA'yı yuklash kabi) PersistenceProviderni avtomatik aniqlash mexanizmini ishlatadi va ko'p hollarda faqat saqlanish birligi nomini belgilash talab etiladi. Quyidagi XML misolida bunday bean sozlangan:
<beans>
<bean id="myEmf" class="org.springframework.orm.jpa.LocalEntityManagerFactoryBean">
<property name="persistenceUnitName" value="myPersistenceUnit"/>
</bean>
</beans>
JPA'ning ushbu shakli eng oddiy va eng cheklangan. JDBC'dan mavjud DataSource bean ta'rifiga murojaat qilish mumkin emas va global tranzaktsiyalarni qo'llab-quvvatlash yo'q. Shuningdek, doimiy sinflarni bog'lash (bayt-kodni o'zgartirish) ma'lum bir yetkazib beruvchiga bog'liq, va ko'pincha ishga tushirishda ma'lum bir JVM agentini belgilash talab etiladi. Bu opsiya faqat standalone dasturlar va sinov muhitlari uchun yetarli bo'ladi, ularning JPA spetsifikatsiyasi ishlab chiqilgan.
EntityManagerFactory'ni JNDI'dan olish
Ushbu variant Java EE serverida deploy qilishda ishlatilishi mumkin. Server haqidagi hujjatlarni ko'rib chiqing, serverda boshqa yetkazib beruvchini ishlatishga imkon beradigan maxsus JPA yetkazib beruvchini deploy qilish yo'liga qarab.
EntityManagerFactory'ni JNDI'dan olish (masalan, Java EE muhitida) XML konfiguratsiyasini o'zgartirish masalasidir, quyidagi misolda ko'rsatilganidek:
<beans>
<jee:jndi-lookup id="myEmf" jndi-name="persistence/myPersistenceUnit"/>
</beans>
Bu harakat standart Java EE yuklashni nazarda tutadi. Java EE serveri avtomatik ravishda saqlanish birliklarini kashf etadi (asosan, META-INF/persistence.xml fayllarini ilovalarning jar-fayllarida) va Java EE deploy qilish deskriptoridagi persistence-unit-ref yozuvlarini (masalan, web.xmlda) topadi va bularga muhit nomlash kontekstini aniqlaydi.
Bunday senariylarda saqlanish birliklarini deploy qilish, sinflarni davomiy saqlashni bog'lash (bayt kodini o'zgartirish) server Java EE tomonidan butunlay bajariladi. JDBC'dan DataSource META-INF/persistence.xml faylida JNDI joylashuvi orqali belgilanadi. EntityManager tranzaksiyalari serverning JTA tizimi qismidir. Spring faqat olingan EntityManagerFactory'dan foydalanadi, uni ilova ob'ektlariga injektsiya orqali yetkazib beradi va saqlanish birligi uchun tranzaksiyalarni boshqaradi (odatda JtaTransactionManager orqali).
Agar bir ilova bir necha saqlanish birliklarini ishlatsa, JNDI'dan olingan bu birliklar nomlari ilova tomonidan ishlatiladigan saqlanish birliklari nomlari bilan mos kelishi kerak (masalan, @PersistenceUnit va @PersistenceContext annotatsiyalarida).
LocalContainerEntityManagerFactoryBean dan foydalanish
Bu variant Spring asosidagi ilovalar muhitida JPA vositalaridan to'liq foydalanish imkonini beradi. Bu Tomcat kabi veb-konteynerlar, standalone dasturlar va murakkab saqlash talablari bilan integratsiya testlarini nazarda tutadi.
LocalContainerEntityManagerFactoryBean'ning oddiy JPA yordamida
LocalSessionFactoryBean'ni foydalanish variantini ko'rib chiqing, bu orqali u JPA kirish kodi bilan hamda Hibernate'ning mahalliy kirish kodi bilan ishlashi mumkin. Batafsil ma'lumotni
JPA bilan o'zaro ishlash uchun Hibernate'ni mahalliy sozlash bo'limida ko'ring.
LocalContainerEntityManagerFactoryBean konfiguratsiyaga to'liq nazorat beradi va o'zgaruvchilarni nozik sozlash talab etilgan muhitlar uchun mos keladi. LocalContainerEntityManagerFactoryBean persistence.xml fayli asosida PersistenceUnitInfo ob'ektlarini yaratadi, uzatilgan dataSourceLookup strategiyasi va belgilangan loadTimeWeaver asosida. Shu tarzda, JNDI'dan chetda maxsus ma'lumot manbalaridan foydalanish va ulanish jarayonini boshqarish mumkin. Quyidagi misolda LocalContainerEntityManagerFactoryBean uchun odatiy bean ta'rifi ko'rsatilgan:
<beans>
<bean id="myEmf" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="dataSource" ref="someDataSource"/>
<property name="loadTimeWeaver">
<bean class="org.springframework.instrument.classloading.InstrumentationLoadTimeWeaver"/>
</property>
</bean>
</beans>
Quyidagi misolda odatiy persistence.xml fayli ko'rsatilgan:
<persistence xmlns="http://java.sun.com/xml/ns/persistence" version="1.0">
<persistence-unit name="myUnit" transaction-type="RESOURCE_LOCAL">
<mapping-file>META-INF/orm.xml</mapping-file>
<exclude-unlisted-classes/>
</persistence-unit>
</persistence>
<exclude-unlisted-classes/> skanerlashni o'z ichiga olmaydi. Aniq qiymati "true" (
<exclude-unlisted-classes>true</exclude-unlisted-classes/>) ham tekshirishni o'z ichiga olmaydi.
<exclude-unlisted-classes>false</exclude-unlisted-classes/> skanerlashni o'z ichiga oladi. Agar sinflarni skanerlash kerak bo'lsa,
exclude-unlisted-classes elementini chiqarishni tavsiya qilamiz.
LocalContainerEntityManagerFactoryBean JPA'ni konfiguratsiya qilishning eng samarali varianti bo'lib, ilovada moslashuvchan lokal konfiguratsiyani ta'minlaydi. Bu JDBC'dan mavjud DataSource'dan foydalanishni qo'llab-quvvatlaydi, mahalliy va global tranzaksiyalarni qo'llab-quvvatlaydi va hokazo. Ammo u bajaruvi muhitiga talablar qo'yadi, masalan, agar saqlanish yetkazib beruvchisi bayt-kod konversiyasiga muhtoj bo'lsa, bog'lanish imkoniyatiga ega bo'lgan sinf yuklagichi mavjudligi.
Ushbu variant Java EE serverining ichki vositalari bilan to'qnashishi mumkin. To'liq funktsional Java EE muhitida EntityManagerFactory'ni JNDI'dan olish imkoniyatini ko'rib chiqing. Yana bir variant sifatida, LocalContainerEntityManagerFactoryBean'da maxsus persistenceXmlLocation belgilang (masalan, META-INF/my-persistence.xml) va faqat shu nomdagi deskriptorni ilovangizning jar-fayllariga qo'shing. Chunki Java EE serveri faqatgina standart fayllarni izlaydi META-INF/persistence.xml, u bunday maxsus saqlash birliklarini e'tiborsiz qoldiradi, bu esa talashishning oldini olishga imkon beradi Spring asosidagi JPA konfiguratsiyasi bilan. (Bu, masalan, Resin 3.1 bilan bog'liq).
LoadTimeWeaver interfeysi – bu Springda bo'lgan sinf, u ClassTransformer namunalari orqali JPA'ni muhitda, veb-konteyner yoki ilova serveri ekanligini aniqlashga imkon beradi. agent orqali ClassTransformers'ni ulash odatda samarasiz. Agentlar butun virtual mashinada ishlaydi va har bir yuklanayotgan sinfni tekshiradi, bu odatda ishlab chiqarish server muhitlarida maqsadga muvofiq emas.
Spring turli muhitlar uchun bir necha LoadTimeWeaver implementatsiyalarini o'z ichiga oladi, bu sinf yuklagichning faqat har bir o'ziga xoslash mumkin, hech bir virtual mashina uchun emas, faqat har bir sinf yuklagich uchun ClassTransformer namunalari qo'llanadi.
To'liq ma'lumot Spring konfigurasiyasi bo'limida mavjud.
Spring konfigurasiyasi bo'limida tavsiflangandek, LoadTimeWeaverni umumiy konteks uchun @EnableLoadTimeWeaving yoki context:load-time-weaver XML elementi yordamida sozlash mumkin. Ushbu global bog'lanish vositasi avtomatik ravishda barcha JPA LocalContainerEntityManagerFactoryBean namunalari tomonidan qabul qilinadi. Quyidagi misolda yuklash vaqtida bog'lanish vositasini sozlashning ustun usuli ko'rsatilgan bo'lib, platformani avtomatik aniqlash (masalan, Tomcat sinf yuklagichi yoki Spring'dan agentchik) va bog'lanish vositasini qo'llab-quvvatlagan barcha beanlarga avtomatik ravishda o'rnatishni ta'minlaydi:
<context:load-time-weaver/>
<bean id="emf" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
...
</bean>
Biroq, agar kerak bo'lsa, quyidagi misolda ko'rsatilganidek, loadTimeWeaver xususiyati orqali qo'lda maxsus bog'lanish vositasini belgilashingiz mumkin:
<bean id="emf" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="loadTimeWeaver">
<bean class="org.springframework.instrument.classloading.ReflectiveLoadTimeWeaver"/>
</property>
</bean>
Qanday qilib yuklanish vaqtida bog'lanish (LTW) amalga oshirilganidan qat'i nazar, ushbu texnik yordamida JPA dasturlari, instrumentationga tayanadigan, maqsad platformasida (masalan, Tomcat) agent ishlatmasdan ishlaydi. Bu ayniqsa muhim, agar xost dastur ilovalari turli xil JPA yetkazib beruvchilaridan foydalansa, chunki JPA o'zgartiruvchilari faqat sinf yuklagichi darajasida qo'llanilib, o'zaro o'ralgan.
Bir nechta saqlash birliklar bilan ishlash
Bir nechta saqlash birliklari joylashuvlarini (masalan, turli xil JAR fayllarda classpathda saqlangan) ishlatadigan ilovalar uchun, Spring PersistenceUnitManager'ni taklif qiladi, u markaziy repository sifatida xizmat qiladi va qimmat bo'lishi mumkin bo'lgan saqlash birliklarining kashf qilinishi jarayonidan qochishga yordam beradi. Standart implementatsiya bir nechta joylashuvlarni belgilash imkonini beradi. Ushbu joylashuvlar tahlil qilish jarayonida tartiblanadi va keyinchalik saqlash birligi nomi orqali olib kelinadi. (Standart holatda classpathda fayllarMETA-INF/persistence.xml izlanadi). Quyidagi misolda bir nechta joylashuvlar sozlangan:
<bean id="pum" class="org.springframework.orm.jpa.persistenceunit.DefaultPersistenceUnitManager">
<property name="persistenceXmlLocations">
<list>
<value>org/springframework/orm/jpa/domain/persistence-multi.xml</value>
<value>classpath:/my/package/**/custom-persistence.xml</value>
<value>classpath*:META-INF/persistence.xml</value>
</list>
</property>
<property name="dataSources">
<map>
<entry key="localDataSource" value-ref="local-db"/>
<entry key="remoteDataSource" value-ref="remote-db"/>
</map>
</property>
<!-- agar ma'lumot manbasi ko'rsatilmagan bo'lsa, ushbu manbadan foydalaning -->
<property name="defaultDataSource" ref="remoteDataSource"/>
</bean>
<bean id="emf" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="persistenceUnitManager" ref="pum"/>
<property name="persistenceUnitName" value="myCustomUnit"/>
</bean>
Standart implementatsiya PersistenceUnitInfo namunalari bilan ishlashga imkon beradi (ular JPA yetkazib beruvchisiga uzatilishidan oldin) deklarativ tarzda (uning barcha joylashgan (hosted) birliklariga ta'sir qiluvchi xususiyatlar orqali) yoki dasturlash orqali (saqlash birliklarini olishga imkon beruvchi PersistenceUnitPostProcessor orqali). Agar PersistenceUnitManager ko'rsatilmagan bo'lsa, uni LocalContainerEntityManagerFactoryBean ichida avtomatik yaratiladi va ishlatiladi.
Fon yuklash
LocalContainerEntityManagerFactoryBean xususiyat orqali fon yuklash xususiyatini qo'llab-quvvatlaydi bootstrapExecutor, quyidagi misolda ko'rsatilganidek:
<bean id="emf" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="bootstrapExecutor">
<bean class="org.springframework.core.task.SimpleAsyncTaskExecutor"/>
</property>
</bean>
JPA yetkazib beruvchini haqiqiy yuklash belgilangan executor'ga uzatiladi va keyinchalik, parallel ravishda, dastur yuklash oqimiga qadar u uzatiladi. Ochiq proksi EntityManagerFactory ilovaning boshqa komponentlariga joylashtirilishi mumkin va hatto EntityManagerFactoryInfo konfiguratsiyasini tekshirishda javob bera oladi. Ammo, agar JPA yetkazib beruvchisi boshqa komponentlar tomonidan murojaat qilinadigan bo'lsa (masalan, createEntityManager chaqiradigan bo'lishi mumkin), ushbu chaqiriqlar fon yuklash tugaguniga qadar bloklanadi. Xususan, agar siz Spring Data JPA'dan foydalansangiz, uning repositoriesini kechikkan yuklashni ham sozlashni unutmang.
JPA asosidagi DAO amalga oshirish: EntityManagerFactory va EntityManager
EntityManagerFactory nusxalari
Thread-Safe bo'lsa ham,
EntityManager nusxalari
Thread-Safe emas. JPA'dan joylashtirilgan
EntityManager JPA spesifikatsiyasiga muvofiq, ilova serverining
JNDI muhitidan olinadigan
EntityManager kabi ishlaydi. Agar mavjud bo'lsa, barcha chaqiriqlarni o'sha vaqtning tranzaktsion
EntityManageriga beriadi. Aks holda, u har bir operatsiya uchun yangidan yaratilgan
EntityManagerga qaytadi, bu uni ishlatishni aslida
Thread-Safe qiladi.
Spring hech qanday import talab qilmasdan, injektsiyalangan EntityManagerFactory yoki EntityManager yordamida oddiy JPA kodini yozish mumkinligini tan oladi. Agar PersistenceAnnotationBeanPostProcessor faollashtirilgan bo'lsa, @PersistenceUnit va @PersistenceContext annotatsiyalarini ham maydon darajasida, ham metod darajasida tan oladi. Quyidagi misolda, @PersistenceUnit annotatsiyasini ishlatgan holda oddiy JPA asosidagi DAO amalga oshirilishi ko'rsatilgan:
public class ProductDaoImpl implements ProductDao {
private EntityManagerFactory emf;
@PersistenceUnit
public void setEntityManagerFactory(EntityManagerFactory emf) {
this.emf = emf;
}
public Collection loadProductsByCategory(String category) {
EntityManager em = this.emf.createEntityManager();
try {
Query query = em.createQuery("from Product as p where p.category = ?1");
query.setParameter(1, category);
return query.getResultList();
}
finally {
if (em != null) {
em.close();
}
}
}
}
class ProductDaoImpl : ProductDao {
private lateinit var emf: EntityManagerFactory
@PersistenceUnit
fun setEntityManagerFactory(emf: EntityManagerFactory) {
this.emf = emf
}
fun loadProductsByCategory(category: String): Collection<*> {
val em = this.emf.createEntityManager()
val query = em.createQuery("from Product as p where p.category = ?1");
query.setParameter(1, category);
return query.resultList;
}
}
Oldingi DAO Spring'dan mustaqildir va Spring ilova kontekstiga yaxshi mos keladi. Shuningdek, DAO EntityManagerFactory standart injektsiyasi uchun annotatsiyalarni qo'llaydi, quyidagi bean ta'rifi misolida ko'rsatilganidek:
<beans>
<!-- JPA annotatsiyalari uchun bean post-protsessor -->
<bean class="org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor"/>
<bean id="myProductDao" class="product.ProductDaoImpl"/>
</beans>
PersistenceAnnotationBeanPostProcessor'ni aniq belgilashga alternativ sifatida, Spring kontekst konfiguratsiyasida context:annotation-config XML elementidan foydalanishni o'ylab ko'ring. Shunday qilib, annotatsiyaga asoslangan konfiguratsiya uchun barcha standart Spring post-protsessorlar avtomatik ravishda ro'yxatdan o'tkaziladi.
Quyidagi misolga e'tibor bering:
<beans>
<!-- Barcha standart annotation konfiguratsiyalari uchun post-protsessorlar -->
<context:annotation-config/>
<bean id="myProductDao" class="product.ProductDaoImpl"/>
</beans>
Ushbu DAO bilan bog'liq asosiy muammo shundaki, u har doim fabrikadan yangi EntityManager yaratadi. Bunga tranzaktsion EntityManager'ni (yoki "umumiy EntityManager" deb ataladi, chunki u haqiqiy tranzaktsion EntityManager uchun umumiy, ip xavfsiz proksi) so'rash orqali qochish mumkin, bu o'rniga injektsiyalanadi. Quyidagi misolda bu qanday amalga oshirilishini ko'rsatib beradi:
public class ProductDaoImpl implements ProductDao {
@PersistenceContext
private EntityManager em;
public Collection loadProductsByCategory(String category) {
Query query = em.createQuery("from Product as p where p.category = :category");
query.setParameter("category", category);
return query.getResultList();
}
}
class ProductDaoImpl : ProductDao {
@PersistenceContext
private lateinit var em: EntityManager
fun loadProductsByCategory(category: String): Collection<*> {
val query = em.createQuery("from Product as p where p.category = :category")
query.setParameter("category", category)
return query.resultList
}
}
@PersistenceContext annotatsiyasi ixtiyoriy type atributiga ega, bu standart holatda PersistenceContextType.TRANSACTION qiymatiga ega. Umumiy proksini olish uchun ushbu standart qiymatdan foydalanish mumkin EntityManager. Alternativa, ya'ni PersistenceContextType.EXTENDED, mutlaqo boshqa ishdir. Natijada, ushbu kengaytirilgan EntityManager ni bunday komponentda, masalan, Spring'da boshqaruvchi singlton bean kabi ishlatish mumkin emas, chunki u ip xavfsiz emas. Kengaytirilgan EntityManager nusxalari to'laqonli foydalanish uchun mo'ljallangan komponentlar uchun mo'ljallangan bo'lib, ularning o'z holatini, masalan, sessiyada saqlaydi, EntityManager'ning umrning o'zi tranzaktsiyaga bog'liq emas, balki to'liq ilovaga bog'liq.
Injektsiya qilingan EntityManagerni Spring boshqaradi (u hozirgi tranzaktsiyani hisobga oladi). Hatto yangi DAO amalga oshirish EntityManager'ni metod darajasida injektsiyalashni ishlatsa ham, EntityManagerFactory o'rniga kontekst konfiguratsiyasi uchun hech qanday XML o'zgartirish kerak emas, chunki annotatsiyalar ishlatiladi.
Ushbu DAO usulining asosiy afzalligi shundaki, u faqat Java Persistence API'ga bog'liq. Spring'dan har qanday sinfni import qilish talab qilinmaydi. Shu bilan birga, JPA annotatsiyalarini tan olish orqali, injektsiya Spring konteyneri tomonidan avtomatik ravishda qo'llaniladi. Bu tajovuzkorlikdan uzoqligi nuqtai nazaridan jozibali va JPA ishlab chiquvchilari uchun tabiiyroq bo'lishi mumkin.
Spring tomonidan boshqariladigan JPA tranzaktsiyalari
JPA uchun tavsiya qilingan strategiya – JPA ning o‘z ichiga olgan tranzaktsiya qo‘llab-quvvatlashi bilan lokal tranzaktsiyalar. Spring'dan JpaTransactionManager lokal JDBC tranzaktsiyalar bilan tanilgan ko'plab vositalarni (masalan, maxsus tranzaktsiya izolyatsiya darajalari va resurs darajasidagi "faqat o'qish uchun" rejimini optimallashtirish) taklif qiladi, har qanday oddiy JDBC ulanish havzasi uchun (XA talab qilmaydi).
Spring orqali JPA, shuningdek, bir xil DataSourcega kiruvchi JDBC kod uchun JpaTransactionManager'ni ochishga imkon beradi, agar roʻyxatdan oʻtgan JpaDialect Connectionni JDBC'dan olishni qoʻllab-quvvatlasa. Spring EclipseLink va Hibernate orqali JPA amalga oshirilishlari uchun dialektlarni o'z ichiga oladi.
HibernateTransactionManager Hibernate'ning ayrim xususiyatlariga moslashish va JDBC bilan o'zaro ta'sir qilish imkonini beradi. Bu ayniqsa
LocalSessionFactoryBean bilan sozlashda mantiqli. Batafsil ma'lumotni
JPA bilan o'zaro ishlash uchun Hibernate'ning mahalliy sozlanishi bo'limida ko'ring.
JpaDialect va JpaVendorAdapter asosiy nuqtalari
Kengaytirilgan imkoniyat sifatida JpaTransactionManager va AbstractEntityManagerFactoryBean sinflari foydalanuvchi tomonidan yaratilgan JpaDialect ni jpaDialect bean xususiyati orqali uzatish imkonini beradi. JpaDialect implementatsiyasi Spring tomonidan qo'llab-quvvatlanadigan quyidagi kengaytirilgan imkoniyatlarni berishi mumkin, odatda ishlab chiqaruvchi tomonidan:
-
Maxsus tranzaktsiya semantikasini qo'llash (masalan, maxsus izolyatsiya darajasi yoki tranzaktsiya kutish vaqti)
-
Tranzaktsion
ConnectionJDBC (JDBCga asoslangan DAO ob'ektlariga o'tkazish uchun) -
Spring'dan
PersistenceExceptionsniDataAccessExceptionsga kengaytirilgan tarzda aylantirish
Bu ayniqsa maxsus tranzaktsiya semantikasida va kengaytirilgan istisno aylantirishda foydali. Standart implementatsiya(DefaultJpaDialect) hech qanday maxsus imkoniyatlarni ta'minlamaydi, va agar yuqorida ko'rsatilgan imkoniyatlar kerak bo'lsa, mos dialektni belgilash zarur.
JpaVendorAdapter Spring'dan
LocalContainerEntityManagerFactoryBean ning to'liq funksiya sozlanishida ishlab chiqaruvchi adaptatsiyasi uchun vosita sifatida
JpaDialect imkoniyatlarini boshqa ishlab chiqaruvchi bo'yicha maxsus parametrlar bilan birlashtiradi.
HibernateJpaVendorAdapter yoki
EclipseLinkJpaVendorAdapter ni belgilash Hibernate yoki EclipseLink uchun
EntityManagerFactoryni avtomatik sozlashning eng qulay usuli hisoblanadi. Bu yetkazib beruvchi adapterlari birinchi navbatda Spring asosidagi tranzaktsiyalarni boshqarish uchun mo'ljallangan (ya'ni
JpaTransactionManager bilan foydalanish uchun).
JpaDialect va JpaVendorAdapter haqida ko'proq ma'lumot olish uchun Spring'ning JPAni qo'llab-quvvatlovchi vositalarida qanday ishlatilishi haqida batafsil ma'lumot uchun javadocga qarang.
JTA orqali tranzaktsiyalarni boshqarish bilan JPA'ni sozlash
JpaTransactionManager'ga alternativa sifatida, Spring bir necha resurs bilan tranzaktsiyalarni JTA orqali ham Java EE muhitida va ham Atomikos kabi alohida tranzaktsiya koordinatori bilan boshqarishga imkon beradi. JpaTransactionManager o'rniga JtaTransactionManager ni tanlashdan tashqari, yana bir necha qadamni amalga oshirish kerak:
-
Asosiy JDBC ulanish havzalari XA bilan mos bo'lishi va sizning tranzaktsiya koordinatoringiz bilan birlashtirilishi kerak. Odatda Java EE muhitida bu sodda tarzda
DataSource'ning boshqa turini JNDI orqali ochish yo'li bilan amalga oshiriladi. Sizning ilova serveringiz hujjatlariga qarang. Xuddi shunday, avtonom tranzaktsiya koordinatori odatda XA bilan biriktirilgan maxsusDataSourcevariantlarini o'z ichiga oladi. Yana, hujjatlardan foydalaning. -
JPA'dagi
EntityManagerFactoryJTA uchun sozlanishi kerak. Barchasi ishlab chiqaruvchiga bog'liq, lekin odatda buLocalContainerEntityManagerFactoryBeanuchunjpaPropertiessifatida belgilanishi kerak bo'lgan maxsus xususiyatlar orqali amalga oshiriladi. Hibernate holatida, bu xususiyatlar hatto versiyaga bog'liq. Hibernate hujjatlariga qarang. -
Spring'dan
HibernateJpaVendorAdapterHorizon 5.0'da Hibernate'nin o'sha maxsus moddaning o'z qiymatiga moslashgan, lekin Horizon 5.1+ da mos kelmasligi, kabi Spring'ga mos keluvchi qiymatlarni, masalan, "on-close" ulanishni bo'shatish rejimini qo'llaydi. JTA ni sozlaganda, saqlash birlikingizni tranzaktsiya turi "JTA" deb e'lon qilinganiga ishonch hosil qiling. Boshqa variant sifatida, Hibernate 5.2 danhibernate.connection.handling_modexususiyatiniDELAYED_ACQUISITION_AND_RELEASE_AFTER_STATEMENTga o'rnating, Horizon'dan mos keluvchi maxsus qiymatni tiklash uchun. "Horizon yordamida ilova serverlaridagi noto'g'ri ogohlantirishlar" bo'limiga qarang. -
Boshqa variant sifatida, ilova serveridan
EntityManagerFactoryni olish imkoniyatini ko'rib chiqing (ya'ni,LocalContainerEntityManagerFactoryBeanning lokal e'lon qilinganidan ko'ra, JNDI qidiruvi orqali). Server tomonidan beriladiganEntityManagerFactorykonfiguratsiyangizda maxsus ta'riflarni talab qiladi, ammo JTA muhitiga moslashtirilgan.
JPA bilan o'zaro ishlash uchun Hibernate ni mahalliy sozlash va mahalliy tranzaktsiyalar
LocalSessionFactoryBean'ning mahalliy sozlanishi va HibernateTransactionManager bilan o'zaro ishlashi @PersistenceContext annotatsiyalari bilan muvofiq keladi. SessionFactory Horizon'dan EntityManagerFactory interfeysini o'zgartiradi, va Horizon'dan Session deskriptori JPA uchun EntityManager dir. Spring'dan JPA qo'llab-quvvatlash vositalari Horizon bilan avtomatik ravishda o'zaro moslashadi.
Shuning uchun Horizon'dan bunday mahalliy sozlash ko'plab senariylarda standart LocalContainerEntityManagerFactoryBean va JpaTransactionManager kombinatsiyasining o'rnini bosishi mumkin, SessionFactory.getCurrentSession() bilan o'zaro ishlash imkonini beradi (HibernateTemplate bilan birga), va bitta mahalliy tranzaktsiya ichida @PersistenceContext EntityManager annotatsiyasini o'z ichiga oladi. Bundan tashqari, ushbu sozlash Horizon'ga yanada yaqinroq integratsiyani va kengaytirilgan konfiguratsiya moslashuvchanligini taqdim etadi, chunki u JPA yuklash shabloni kontraktlari bilan cheklangan emas.
Bunday holda, HibernateJpaVendorAdapter konfiguratsiyasi kerak emas, chunki Spring yordami Horizon nativ sozlashi yanada ko'proq imkoniyatlarni taqdim etadi (masalan, maxsus Horizon Neutraler Configurator, Horizon 5.3 dan bean konteyner bilan integratsiya va "faqat o'qish uchun" holatda tranzaktsiyalarni yanada qat'iy optimallashtirish). Yakuniy bosqichda, Horizon'ni mahalliy sozlashingizni LocalSessionFactoryBuilder orqali ifodalashingiz mumkin, bu @Bean annotatsiya asosidagi konfiguratsiyani iteratsiya qilishni osonlik bilan amalga oshiradi (FactoryBean ishlatmasdan).
LocalSessionFactoryBean va LocalSessionFactoryBuilder, LocalContainerEntityManagerFactoryBean JPA'dan bo'lgani kabi, fon yuklashni qo'llab-quvvatlaydi. "Fon yuklash" bo'limida ko'rsatilgan kirish ma'lumot uchun qarang.
LocalSessionFactoryBean uchun bu bootstrapExecutor xususiyati orqali mavjud. LocalSessionFactoryBuilder'dagi dasturiy xususiyat buildSessionFactory yuklash boshlang'ichini amalga oshirish uchun argumentni qabul qiladi.
GO TO FULL VERSION