可行的DeltaSpike教程
在一個最近的項目中,我遇到了一個有趣的問題:采用被賦予單個對象的服務方法,并在一個夜間過程的上下文中重用相同的代碼,該過程獨立于應用程序而在數千個相同類型的對象上運行。
試圖在兩個地方維護如此大小和復雜性的相同過程真是荒謬的,所以我需要找到一種共享代碼的方法。 一種可能的解決方案是使用DeltaSpike (Apache的CDI擴展集合)提供一種從主要Java / JPA / Hibernate應用程序訪問實體和類的簡單方法。
似乎有足夠的文檔來使DeltaSpike在網絡上的類似情況下運行,但是人們對此應用程序的可行性持懷疑態度。 我的團隊無法使它在項目的其他部分工作,因此繼續使用Spring Batch。
最大的障礙是無法創建功能性的EntityManager,無論他們如何緊密地遵循可以找到的文檔和示例。 該項目的較小部分為實現DeltaSpike提供了另一個很好的候選人,但是在對以下教程非常熟悉之后,找到了操作方法,并閱讀了正式的實現說明,我被困在同一個地方:EntityManager將無法工作,至少不能與我面前的技術和版本組合使用。
幸運的是,我能夠將弗蘭肯斯坦的一些教程和示例中的部分放在一起,以針對我的情況獲得可行的DeltaSpike實現,因此我想我會分享我發現的內容,因此下次其他人可能會更輕松一些。
基礎
首先,我正在使用Maven,因此這里是您需要添加的依賴項:
<dependency><groupId>org.apache.deltaspike.cdictrl</groupId><artifactId>deltaspike-cdictrl-api</artifactId><version>1.2.1</version><scope>compile</scope> </dependency><dependency><groupId>org.jboss.weld.se</groupId><artifactId>weld-se</artifactId><version>1.1.16.Final</version><scope>runtime</scope> </dependency><dependency><groupId>org.apache.deltaspike.cdictrl</groupId><artifactId>deltaspike-cdictrl-weld</artifactId><version>1.2.1</version><scope>runtime</scope> </dependency><dependency><groupId>org.apache.deltaspike.core</groupId><artifactId>deltaspike-core-api</artifactId><version>1.5.0</version> </dependency><dependency><groupId>org.apache.deltaspike.modules</groupId><artifactId>deltaspike-jpa-module-api</artifactId><version>1.4.0</version> </dependency><dependency><groupId>org.apache.deltaspike.modules</groupId><artifactId>deltaspike-jpa-module-impl</artifactId><version>1.4.0</version> </dependency>如您所見,我們正在考慮在一個也需要JBoss / Weld的項目中實現DeltaSpike。 我所依賴的其他依賴項包括javax.enterprise,Hibernate和JPA。 根據最終的實現,您可能不需要所有這些DeltaSpike依賴項,因此請確保在完成后清理pom.xml。
應用程式
對于我的示例,我將使用一個基本的Application類,該類遵循您在其他DeltaSpike示例中可能看到的模式:
import javax.enterprise.context.ApplicationScoped; import org.apache.deltaspike.cdise.api.CdiContainer; import org.apache.deltaspike.cdise.api.CdiContainerLoader; import org.apache.deltaspike.cdise.api.ContextControl; import org.apache.deltaspike.core.api.config.ConfigResolver;public class Application {public static void main(String[] args) {CdiContainer cdiContainer = CdiContainerLoader.getCdiContainer();cdiContainer.boot();ContextControl contextControl = cdiContainer.getContextControl();contextControl.startContext(ApplicationScoped.class);//Your code herecdiContainer.shutdown();} }特別注意這一行:
contextControl.startContext(ApplicationScoped.class);該行查找帶有@ApplicationScoped批注的類,這些類需要包含在上下文中。
EntityManagerProducer
這是棘手的地方。 遵循典型的DeltaSpike教程,將為您提供一個類似于以下內容的EntityManagerProducer:
@ApplicationScoped public class EntityManagerProducer {@PersistenceUnitprivate EntityManagerFactory entityManagerFactory;@Produces@Default@RequestScopedpublic EntityManager create(){return this.entityManagerFactory.createEntityManager();}public void dispose(@Disposes @Default EntityManager entityManager){if (entityManager.isOpen()){entityManager.close();}} }考慮到我要處理的各種因素,我唯一遇到的問題是根本不起作用。 無論我嘗試了什么,EntityManager始終為null。 我懷疑EntityManagerFactory不能正常工作,所以我做了一些挖掘,發現這種獲取EntityManagerFactory的方法:
private EntityManagerFactory entityManagerFactory = Persistence.createEntityManagerFactory("PERSISTENCE_UNIT", setProperties());使用此方法,我可以基于在persistence.xml中定義的持久性單元(它具有我在參數中提供的名稱)來獲得一個有效的EntityManagerFactory。 在這里,我定義了應用程序需要成為EntityManagerFactory一部分的實體,以便能夠執行諸如運行之類的小事情。
這是新的和改進的EntityManagerProducer的外觀:
@ApplicationScoped public class EntityManagerProducer {private EntityManagerFactory entityManagerFactory = Persistence.createEntityManagerFactory("PERSISTENCE_UNIT", setProperties());private EntityManager entityManager;protected void closeEntityManager(@Disposes EntityManager entityManager) {if (entityManager.isOpen()) {entityManager.close();}}@Producesprotected EntityManager createEntityManager() {if (entityManager == null) {entityManager = entityManagerFactory.createEntityManager();}return entityManager;}protected Properties setProperties() {properties.setProperty("hibernate.dialect", "org.hibernate.dialect.Oracle10gDialect");properties.setProperty("hibernate.show_sql", "false");properties.setProperty("hibernate.hbm2ddl.auto", "none");properties.setProperty("hibernate.enable_lazy_load_no_trans", "true");properties.setProperty("hibernate.jdbc.batch_size", "20");properties.setProperty("hibernate.connection.driver_class", "oracle.jdbc.driver.OracleDriver");properties.setProperty("hibernate.connection.url", "JDBC_URL");properties.setProperty("hibernate.default_schema", System.getProperty("SCHEMA_NAME"));properties.setProperty("javax.persistence.jdbc.user", System.getProperty("USER"));properties.setProperty("javax.persistence.jdbc.password", System.getProperty("PASSWORD"));properties.setProperty("org.hibernate.flushMode", "ALWAYS");return properties;}}注意@ApplicationScoped標簽; 這樣可以確保在啟動CDI容器時將此類包含在上下文中。 還要注意,您可以設置屬性以將其傳遞到您創建的EntityManagerFactory中,包括從服務器參數中的系統屬性中獲取它們,如果環境變量可能會更改應用程序的功能,這將非常有用。
最后的想法
希望這為如何設置和實現DeltaSpike提供了一個簡單有效的示例。
旁注:我最終無法使用這種方法來解決問題,因為要處理的對象數量比預期的要大得多(幾百萬個),但是我認為分享發現的內容仍然有用。
翻譯自: https://www.javacodegeeks.com/2016/01/working-deltaspike-tutorial.html
總結
以上是生活随笔為你收集整理的可行的DeltaSpike教程的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 手机扫描快捷键大全(手机扫一扫快捷键)
- 下一篇: 身份证水印怎么加安全 身份证水印如何加安