This is an automated email from the ASF dual-hosted git repository.

arnold pushed a commit to branch develop
in repository https://gitbox.apache.org/repos/asf/fineract.git


The following commit(s) were added to refs/heads/develop by this push:
     new 3cd4db820 FINERACT-1724: Ability to customize the EntityManagerFactory 
from custom modules
3cd4db820 is described below

commit 3cd4db8209027aa53fd0c1f6b430b5199ec9eb04
Author: Arnold Galovics <[email protected]>
AuthorDate: Wed Oct 19 14:16:18 2022 +0200

    FINERACT-1724: Ability to customize the EntityManagerFactory from custom
    modules
---
 .../config/jpa/EntityManagerFactoryCustomizer.java | 64 ++++++++++++++++++++++
 .../core/config/{ => jpa}/JPAConfig.java           | 50 +++++++++++++----
 2 files changed, 102 insertions(+), 12 deletions(-)

diff --git 
a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/config/jpa/EntityManagerFactoryCustomizer.java
 
b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/config/jpa/EntityManagerFactoryCustomizer.java
new file mode 100644
index 000000000..e2a77c959
--- /dev/null
+++ 
b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/config/jpa/EntityManagerFactoryCustomizer.java
@@ -0,0 +1,64 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.fineract.infrastructure.core.config.jpa;
+
+import java.util.Collections;
+import java.util.Map;
+import java.util.Set;
+import 
org.springframework.orm.jpa.persistenceunit.PersistenceUnitPostProcessor;
+
+/**
+ * A customizer interface for the EntityManager factories. Register an 
implementation of this interface as a Spring
+ * bean, and it'll be picked up automatically. <br>
+ * <br>
+ * Multiple customizers could be registered and all of them will be picked up 
by the application. <br>
+ * <br>
+ * The order in which the customizations are applied is not guaranteed.
+ *
+ * @see JPAConfig
+ */
+public interface EntityManagerFactoryCustomizer {
+
+    /**
+     * Additional packages to scan, for example in case of custom modules.
+     *
+     * @return a Set of package names, not null
+     */
+    default Set<String> additionalPackagesToScan() {
+        return Collections.emptySet();
+    }
+
+    /**
+     * Additional vendor properties to be passed to EclipseLink; useful in 
case of fine-tuning.
+     *
+     * @return a Set of vendor properties, not null
+     */
+    default Map<String, Object> additionalVendorProperties() {
+        return Collections.emptyMap();
+    }
+
+    /**
+     * Additional {@link PersistenceUnitPostProcessor} configuration in case 
customizations are required.
+     *
+     * @return Set of PersistenceUnitPostProcessors, not null
+     */
+    default Set<PersistenceUnitPostProcessor> 
additionalPersistenceUnitPostProcessors() {
+        return Collections.emptySet();
+    }
+}
diff --git 
a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/config/JPAConfig.java
 
b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/config/jpa/JPAConfig.java
similarity index 70%
rename from 
fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/config/JPAConfig.java
rename to 
fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/config/jpa/JPAConfig.java
index 2061fdb6e..77c1f7866 100644
--- 
a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/config/JPAConfig.java
+++ 
b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/core/config/jpa/JPAConfig.java
@@ -17,9 +17,13 @@
  * under the License.
  */
 
-package org.apache.fineract.infrastructure.core.config;
+package org.apache.fineract.infrastructure.core.config.jpa;
 
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.HashSet;
 import java.util.Map;
+import java.util.Set;
 import 
org.apache.fineract.infrastructure.core.auditing.JpaAuditingHandlerRegistrar;
 import org.apache.fineract.infrastructure.core.domain.AuditorAwareImpl;
 import 
org.apache.fineract.infrastructure.core.persistence.DatabaseSelectingPersistenceUnitPostProcessor;
@@ -43,6 +47,7 @@ import 
org.springframework.data.jpa.repository.config.EnableJpaRepositories;
 import org.springframework.orm.jpa.JpaVendorAdapter;
 import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
 import org.springframework.orm.jpa.persistenceunit.PersistenceUnitManager;
+import 
org.springframework.orm.jpa.persistenceunit.PersistenceUnitPostProcessor;
 import org.springframework.orm.jpa.vendor.AbstractJpaVendorAdapter;
 import org.springframework.orm.jpa.vendor.EclipseLinkJpaVendorAdapter;
 import org.springframework.transaction.PlatformTransactionManager;
@@ -57,11 +62,13 @@ import 
org.springframework.transaction.support.TransactionTemplate;
 public class JPAConfig extends JpaBaseConfiguration {
 
     private final DatabaseTypeResolver databaseTypeResolver;
+    private final Collection<EntityManagerFactoryCustomizer> 
emFactoryCustomizers;
 
     public JPAConfig(RoutingDataSource dataSource, JpaProperties properties, 
ObjectProvider<JtaTransactionManager> jtaTransactionManager,
-            DatabaseTypeResolver databaseTypeResolver) {
+            DatabaseTypeResolver databaseTypeResolver, 
Collection<EntityManagerFactoryCustomizer> customizers) {
         super(dataSource, properties, jtaTransactionManager);
         this.databaseTypeResolver = databaseTypeResolver;
+        this.emFactoryCustomizers = customizers;
     }
 
     @Override
@@ -70,9 +77,27 @@ public class JPAConfig extends JpaBaseConfiguration {
     @DependsOn("tenantDatabaseUpgradeService")
     public LocalContainerEntityManagerFactoryBean 
entityManagerFactory(EntityManagerFactoryBuilder factoryBuilder) {
         Map<String, Object> vendorProperties = getVendorProperties();
-        customizeVendorProperties(vendorProperties);
-        return 
factoryBuilder.dataSource(getDataSource()).properties(vendorProperties).persistenceUnit("jpa-pu")
-                .packages("org.apache.fineract").jta(false).build();
+        String[] packagesToScan = getPackagesToScan();
+        return 
factoryBuilder.dataSource(getDataSource()).properties(vendorProperties).persistenceUnit("jpa-pu").packages(packagesToScan)
+                .jta(false).build();
+    }
+
+    @Override
+    protected Map<String, Object> getVendorProperties() {
+        Map<String, Object> vendorProperties = new HashMap<>();
+        vendorProperties.put(PersistenceUnitProperties.WEAVING, "static");
+        
vendorProperties.put(PersistenceUnitProperties.PERSISTENCE_CONTEXT_CLOSE_ON_COMMIT,
 "true");
+        vendorProperties.put(PersistenceUnitProperties.CACHE_SHARED_DEFAULT, 
"false");
+        emFactoryCustomizers.forEach(c -> 
vendorProperties.putAll(c.additionalVendorProperties()));
+        return vendorProperties;
+    }
+
+    @Override
+    protected String[] getPackagesToScan() {
+        Set<String> packagesToScan = new HashSet<>();
+        packagesToScan.add("org.apache.fineract");
+        emFactoryCustomizers.forEach(c -> 
packagesToScan.addAll(c.additionalPackagesToScan()));
+        return packagesToScan.toArray(String[]::new);
     }
 
     @Override
@@ -80,19 +105,20 @@ public class JPAConfig extends JpaBaseConfiguration {
             ObjectProvider<PersistenceUnitManager> persistenceUnitManager,
             ObjectProvider<EntityManagerFactoryBuilderCustomizer> customizers) 
{
         EntityManagerFactoryBuilder builder = 
super.entityManagerFactoryBuilder(jpaVendorAdapter, persistenceUnitManager, 
customizers);
-        builder.setPersistenceUnitPostProcessors(new 
DatabaseSelectingPersistenceUnitPostProcessor(databaseTypeResolver));
+        
builder.setPersistenceUnitPostProcessors(getPersistenceUnitPostProcessors());
         return builder;
     }
 
-    @Override
-    protected AbstractJpaVendorAdapter createJpaVendorAdapter() {
-        return new EclipseLinkJpaVendorAdapter();
+    private PersistenceUnitPostProcessor[] getPersistenceUnitPostProcessors() {
+        Set<PersistenceUnitPostProcessor> processors = new HashSet<>();
+        processors.add(new 
DatabaseSelectingPersistenceUnitPostProcessor(databaseTypeResolver));
+        emFactoryCustomizers.forEach(c -> 
processors.addAll(c.additionalPersistenceUnitPostProcessors()));
+        return processors.toArray(PersistenceUnitPostProcessor[]::new);
     }
 
     @Override
-    protected Map<String, Object> getVendorProperties() {
-        return Map.of(PersistenceUnitProperties.WEAVING, "static", 
PersistenceUnitProperties.PERSISTENCE_CONTEXT_CLOSE_ON_COMMIT, "true",
-                PersistenceUnitProperties.CACHE_SHARED_DEFAULT, "false");
+    protected AbstractJpaVendorAdapter createJpaVendorAdapter() {
+        return new EclipseLinkJpaVendorAdapter();
     }
 
     @Bean

Reply via email to