You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@openjpa.apache.org by rm...@apache.org on 2020/04/29 18:47:39 UTC

[openjpa] 01/02: OPENJPA-2813 PersistenceProvider#generateSchema (misses the boolean state)

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

rmannibucau pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/openjpa.git

commit bf418eb1b3036f49d9536db66e30ef7ceb83332d
Author: Romain Manni-Bucau <rm...@gmail.com>
AuthorDate: Wed Apr 29 20:47:12 2020 +0200

    OPENJPA-2813 PersistenceProvider#generateSchema (misses the boolean state)
---
 .../openjpa/jdbc/kernel/JDBCBrokerFactory.java     | 11 +++--
 .../persistence/PersistenceProviderImpl.java       | 54 ++++++++++++++++++++--
 .../slice/jdbc/DistributedJDBCBrokerFactory.java   |  6 ++-
 3 files changed, 60 insertions(+), 11 deletions(-)

diff --git a/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/JDBCBrokerFactory.java b/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/JDBCBrokerFactory.java
index 1597c00..ecf0f8c 100644
--- a/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/JDBCBrokerFactory.java
+++ b/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/JDBCBrokerFactory.java
@@ -147,17 +147,17 @@ public class JDBCBrokerFactory extends AbstractBrokerFactory {
     /**
      * Synchronize the mappings of the classes listed in the configuration.
      */
-    protected void synchronizeMappings(ClassLoader loader,
+    protected boolean synchronizeMappings(ClassLoader loader,
         JDBCConfiguration conf) {
         mapSchemaGenerationToSynchronizeMappings(conf);
         String action = conf.getSynchronizeMappings();
         if (StringUtil.isEmpty(action))
-            return;
+            return false;
 
         MappingRepository repo = conf.getMappingRepositoryInstance();
         Collection<Class<?>> classes = repo.loadPersistentTypes(false, loader);
         if (classes.isEmpty())
-            return;
+            return false;
 
         String props = Configurations.getProperties(action);
         action = Configurations.getClassName(action);
@@ -175,10 +175,11 @@ public class JDBCBrokerFactory extends AbstractBrokerFactory {
             }
         }
         tool.record();
+        return true; // todo: check?
     }
 
-    protected void synchronizeMappings(ClassLoader loader) {
-        synchronizeMappings(loader, (JDBCConfiguration) getConfiguration());
+    protected boolean synchronizeMappings(ClassLoader loader) {
+        return synchronizeMappings(loader, (JDBCConfiguration) getConfiguration());
     }
 
     private void mapSchemaGenerationToSynchronizeMappings(JDBCConfiguration conf) {
diff --git a/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/PersistenceProviderImpl.java b/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/PersistenceProviderImpl.java
index 1d337af..0b6d998 100644
--- a/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/PersistenceProviderImpl.java
+++ b/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/PersistenceProviderImpl.java
@@ -20,6 +20,8 @@ package org.apache.openjpa.persistence;
 
 import java.lang.instrument.ClassFileTransformer;
 import java.lang.instrument.IllegalClassFormatException;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
 import java.security.ProtectionDomain;
 import java.util.HashMap;
 import java.util.Map;
@@ -36,6 +38,7 @@ import org.apache.openjpa.conf.OpenJPAConfiguration;
 import org.apache.openjpa.conf.OpenJPAConfigurationImpl;
 import org.apache.openjpa.enhance.PCClassFileTransformer;
 import org.apache.openjpa.enhance.PCEnhancerAgent;
+import org.apache.openjpa.kernel.AbstractBrokerFactory;
 import org.apache.openjpa.kernel.Bootstrap;
 import org.apache.openjpa.kernel.BrokerFactory;
 import org.apache.openjpa.kernel.ConnectionRetainModes;
@@ -223,13 +226,56 @@ public class PersistenceProviderImpl
     }
 
     @Override
-    public void generateSchema(PersistenceUnitInfo info, Map map) {
-        throw new UnsupportedOperationException("JPA 2.1");
+    public void generateSchema(final PersistenceUnitInfo info, final Map map) {
+        final Map runMap = map == null ? new HashMap<>() : new HashMap<>(map);
+        runMap.put("javax.persistence.schema-generation.database.action", "create");
+        final OpenJPAEntityManagerFactory factory = createContainerEntityManagerFactory(info, runMap);
+        try {
+            synchronizeMappings(factory);
+        } finally {
+            factory.close();
+        }
     }
 
     @Override
-    public boolean generateSchema(String persistenceUnitName, Map map) {
-        throw new UnsupportedOperationException("JPA 2.1");
+    public boolean generateSchema(final String persistenceUnitName, final Map map) {
+        final Map runMap = map == null ? new HashMap<>() : new HashMap<>(map);
+        runMap.put("javax.persistence.schema-generation.database.action", "create");
+        final OpenJPAEntityManagerFactory factory = createEntityManagerFactory(persistenceUnitName, runMap);
+        try {
+            final Object obj = synchronizeMappings(factory);
+            return Boolean.class.cast(obj) ? Boolean.class.cast(obj) : true;
+        } finally {
+            factory.close();
+        }
+    }
+
+    private Object synchronizeMappings(final OpenJPAEntityManagerFactory factory) {
+        if (EntityManagerFactoryImpl.class.isInstance(factory)) {
+            final EntityManagerFactoryImpl entityManagerFactory = EntityManagerFactoryImpl.class.cast(factory);
+            final BrokerFactory brokerFactory = entityManagerFactory.getBrokerFactory();
+            if (!AbstractBrokerFactory.class.isInstance(brokerFactory)) {
+                throw new IllegalArgumentException("expected AbstractBrokerFactory but got " + brokerFactory);
+            }
+            try {
+                final Method synchronizeMappings = brokerFactory.getClass()
+                        .getDeclaredMethod("synchronizeMappings", ClassLoader.class);
+                if (!synchronizeMappings.isAccessible()) {
+                    synchronizeMappings.setAccessible(true);
+                }
+                return synchronizeMappings.invoke(brokerFactory, Thread.currentThread().getContextClassLoader());
+            } catch (final NoSuchMethodException | IllegalAccessException e) {
+                throw new IllegalStateException(e);
+            } catch (final InvocationTargetException e) {
+                final Throwable targetException = e.getTargetException();
+                if (RuntimeException.class.isInstance(targetException)) {
+                    throw RuntimeException.class.cast(targetException);
+                }
+                throw new IllegalStateException(targetException);
+            }
+        } else {
+            throw new IllegalArgumentException("expected EntityManagerFactoryImpl but got " + factory);
+        }
     }
 
     public void setPersistenceEnvironmentInfo(OpenJPAConfiguration conf, PersistenceUnitInfo pui) {
diff --git a/openjpa-slice/src/main/java/org/apache/openjpa/slice/jdbc/DistributedJDBCBrokerFactory.java b/openjpa-slice/src/main/java/org/apache/openjpa/slice/jdbc/DistributedJDBCBrokerFactory.java
index 6dc2451..9973ba2 100644
--- a/openjpa-slice/src/main/java/org/apache/openjpa/slice/jdbc/DistributedJDBCBrokerFactory.java
+++ b/openjpa-slice/src/main/java/org/apache/openjpa/slice/jdbc/DistributedJDBCBrokerFactory.java
@@ -120,11 +120,13 @@ public class DistributedJDBCBrokerFactory extends JDBCBrokerFactory
     }
 
     @Override
-    protected void synchronizeMappings(ClassLoader loader) {
+    protected boolean synchronizeMappings(ClassLoader loader) {
         List<Slice> slices = getConfiguration().getSlices(Slice.Status.ACTIVE);
+        boolean result = false;
         for (Slice slice : slices) {
-            synchronizeMappings(loader, (JDBCConfiguration) slice.getConfiguration());
+            result = synchronizeMappings(loader, (JDBCConfiguration) slice.getConfiguration()) || result;
         }
+        return result;
     }
 
     @Override