| /* |
| * 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.openjpa.persistence.test; |
| |
| import java.io.ByteArrayInputStream; |
| import java.io.ByteArrayOutputStream; |
| import java.io.IOException; |
| import java.io.ObjectInputStream; |
| import java.io.ObjectOutputStream; |
| import java.lang.reflect.Constructor; |
| import java.lang.reflect.InvocationTargetException; |
| import java.lang.reflect.Method; |
| import java.lang.reflect.Modifier; |
| import java.sql.SQLException; |
| import java.util.ArrayList; |
| import java.util.HashMap; |
| import java.util.List; |
| import java.util.Map; |
| |
| import javax.persistence.Cache; |
| import javax.persistence.EntityManager; |
| import javax.persistence.EntityManagerFactory; |
| import javax.persistence.Persistence; |
| |
| import org.apache.openjpa.jdbc.conf.JDBCConfiguration; |
| import org.apache.openjpa.jdbc.sql.DBDictionary; |
| import org.apache.openjpa.kernel.AbstractBrokerFactory; |
| import org.apache.openjpa.kernel.Broker; |
| import org.apache.openjpa.meta.ClassMetaData; |
| import org.apache.openjpa.persistence.JPAFacadeHelper; |
| import org.apache.openjpa.persistence.OpenJPAEntityManagerFactory; |
| import org.apache.openjpa.persistence.OpenJPAEntityManagerFactorySPI; |
| import org.apache.openjpa.persistence.OpenJPAPersistence; |
| |
| import junit.framework.TestCase; |
| import junit.framework.TestResult; |
| |
| /** |
| * Base class for Persistence TestCases. This class contains utility methods but does not maintain an EntityManager or |
| * EntityManagerFactory - these tasks are left for subclasses to handle. Extends junit.framework.TestCase and |
| * performs NO automatic clean up of EMFs created by createEMF() or createNamedEMF(). |
| */ |
| public abstract class AbstractPersistenceTestCase extends TestCase { |
| public static final String FRESH_EMF = "Creates new EntityManagerFactory"; |
| public static final String RETAIN_DATA = "Retain data after test run"; |
| private boolean retainDataOnTearDown; |
| protected boolean _fresh = false; |
| private Boolean testsDisabled = Boolean.FALSE; |
| |
| public static final String ALLOW_FAILURE_LOG = "log"; |
| public static final String ALLOW_FAILURE_IGNORE = "ignore"; |
| public static final String ALLOW_FAILURE_SYS_PROP = "tests.openjpa.allowfailure"; |
| |
| private static String allowFailureConfig = System.getProperty(ALLOW_FAILURE_SYS_PROP, ALLOW_FAILURE_IGNORE); |
| /** |
| * Marker object you pass to {@link #setUp} to indicate that the database table rows should be cleared. |
| */ |
| protected static final Object CLEAR_TABLES = new Object(); |
| |
| /** |
| * Marker object you pass to {@link #setUp} to indicate that the database table should be dropped and then |
| * recreated. |
| */ |
| protected static final Object DROP_TABLES = new Object(); |
| |
| /** |
| * The {@link TestResult} instance for the current test run. |
| */ |
| protected TestResult testResult; |
| |
| /** |
| * Create an entity manager factory. Put {@link #CLEAR_TABLES} in this list to tell the test framework to delete all |
| * table contents before running the tests. |
| * NOTE: Caller must close the returned EMF. |
| * |
| * @param props |
| * list of persistent types used in testing and/or configuration values in the form |
| * key,value,key,value... |
| */ |
| protected OpenJPAEntityManagerFactorySPI createEMF(final Object... props) { |
| return createNamedEMF(getPersistenceUnitName(), props); |
| } |
| |
| /** |
| * The name of the persistence unit that this test class should use by default. This defaults to "test". |
| */ |
| protected String getPersistenceUnitName() { |
| return "test"; |
| } |
| |
| /** |
| * Create an entity manager factory for persistence unit <code>pu</code>. Put {@link #CLEAR_TABLES} in this list to |
| * tell the test framework to delete all table contents before running the tests. |
| * NOTE: Caller must close the returned EMF. |
| * |
| * @param props |
| * list of persistent types used in testing and/or configuration values in the form |
| * key,value,key,value... |
| */ |
| protected OpenJPAEntityManagerFactorySPI createNamedEMF(final String pu, Object... props) { |
| Map<String, Object> map = getPropertiesMap(props); |
| OpenJPAEntityManagerFactorySPI oemf = null; |
| Map<Object, Object> config = new HashMap<>(System.getProperties()); |
| config.putAll(map); |
| oemf = (OpenJPAEntityManagerFactorySPI) Persistence.createEntityManagerFactory(pu, config); |
| if (oemf == null) { |
| throw new NullPointerException("Expected an entity manager factory " + "for the persistence unit named: \"" |
| + pu + "\""); |
| } |
| return oemf; |
| } |
| |
| /** |
| * Create an entity manager factory for persistence unit <code>pu</code>. Put {@link #CLEAR_TABLES} in this list to |
| * tell the test framework to delete all table contents before running the tests. |
| * NOTE: Caller must close the returned EMF. |
| * |
| * @param props |
| * list of persistent types used in testing and/or configuration values in the form |
| * key,value,key,value... |
| */ |
| protected OpenJPAEntityManagerFactorySPI createNamedOpenJPAEMF(final String pu, |
| String res, Map<String,Object> props) { |
| OpenJPAEntityManagerFactorySPI oemf = null; |
| Map<Object, Object> config = new HashMap<>(System.getProperties()); |
| if (props != null) |
| config.putAll(props); |
| oemf = (OpenJPAEntityManagerFactorySPI) OpenJPAPersistence.createEntityManagerFactory(pu, res, props); |
| if (oemf == null) { |
| throw new NullPointerException("Expected an OpenJPA entity manager factory " + |
| "for the persistence unit named: \"" + pu + "\""); |
| } |
| return oemf; |
| } |
| |
| protected Map<String, Object> getPropertiesMap(Object... props) { |
| Map<String, Object> map = new HashMap<>(); |
| map.put("openjpa.DynamicEnhancementAgent", "false"); |
| List<Class<?>> types = new ArrayList<>(); |
| boolean prop = false; |
| |
| for (int i = 0; props != null && i < props.length; i++) { |
| if (props[i] == FRESH_EMF) { |
| _fresh = true; |
| continue; |
| } |
| if (props[i] == RETAIN_DATA) { |
| retainDataOnTearDown = true; |
| continue; |
| } |
| if (prop) { |
| map.put((String) props[i - 1], props[i]); |
| prop = false; |
| } else if (props[i] == CLEAR_TABLES) { |
| map.put("openjpa.jdbc.SynchronizeMappings", "buildSchema(ForeignKeys=true," |
| + "SchemaAction='add,deleteTableContents')"); |
| } else if (props[i] == DROP_TABLES) { |
| map.put("openjpa.jdbc.SynchronizeMappings", "buildSchema(ForeignKeys=true," |
| + "SchemaAction='drop,add')"); |
| } else if (props[i] instanceof Class<?>) { |
| types.add((Class<?>) props[i]); |
| } |
| else if (props[i] instanceof Class<?>[]) { |
| for(Class<?> clss : (Class<?>[]) props[i]) { |
| types.add(clss); |
| } |
| } |
| else if (props[i] != null) { |
| prop = true; |
| } |
| } |
| |
| if (!types.isEmpty()) { |
| StringBuilder buf = new StringBuilder(); |
| for (Class<?> c : types) { |
| if (buf.length() > 0) { |
| buf.append(";"); |
| } |
| buf.append(c.getName()); |
| } |
| String oldValue = |
| map.containsKey("openjpa.MetaDataFactory") ? "," + map.get("openjpa.MetaDataFactory").toString() : ""; |
| map.put("openjpa.MetaDataFactory", "jpa(Types=" + buf.toString() + oldValue + ")"); |
| } else { |
| map.put("openjpa.MetaDataFactory", "jpa"); |
| } |
| return map; |
| } |
| |
| @Override |
| public void run(TestResult testResult) { |
| this.testResult = testResult; |
| super.run(testResult); |
| } |
| |
| @Override |
| public void tearDown() throws Exception { |
| try { |
| super.tearDown(); |
| } catch (Exception e) { |
| // if a test failed, swallow any exceptions that happen |
| // during tear-down, as these just mask the original problem. |
| if (testResult.wasSuccessful()) { |
| throw e; |
| } |
| } |
| } |
| |
| /** |
| * Safely close the given factory. |
| */ |
| protected boolean closeEMF(EntityManagerFactory emf) { |
| boolean brc; |
| if (emf == null || !emf.isOpen()) { |
| return false; |
| } |
| try { |
| closeAllOpenEMs(emf); |
| } finally { |
| emf.close(); |
| brc = !emf.isOpen(); |
| if (!brc) { |
| System.err.println("AbstractPersistenceTestCase().closeEMF() - EMF is still open."); |
| } |
| } |
| return brc; |
| } |
| |
| /** |
| * Safely close the given EM |
| * |
| * @param em |
| */ |
| protected boolean closeEM(EntityManager em) { |
| if (em == null || !em.isOpen()) { |
| return false; |
| } |
| if (em.getTransaction().isActive()) { |
| em.getTransaction().rollback(); |
| } |
| em.close(); |
| boolean brc = !em.isOpen(); |
| if (!brc) { |
| System.err.println("AbstractPersistenceTestCase().closeEM() - EM is still open."); |
| } |
| return brc; |
| } |
| |
| /** |
| * Closes all open entity managers after first rolling back any open transactions. |
| */ |
| protected void closeAllOpenEMs(EntityManagerFactory emf) { |
| if (emf == null || !emf.isOpen()) { |
| return; |
| } |
| |
| for (Broker b : ((AbstractBrokerFactory) JPAFacadeHelper.toBrokerFactory(emf)).getOpenBrokers()) { |
| if (b != null && !b.isClosed()) { |
| EntityManager em = JPAFacadeHelper.toEntityManager(b); |
| if( em.getTransaction().isActive() ) { |
| try { |
| em.getTransaction().rollback(); |
| } catch (Exception e) { |
| } |
| } |
| closeEM(em); |
| } |
| } |
| } |
| |
| /** |
| * Delete all instances of the given types using bulk delete queries, but do not close any open entity managers. |
| */ |
| protected void clear(EntityManagerFactory emf, Class<?>... types) { |
| if (emf == null || types.length == 0) { |
| return; |
| } |
| |
| List<ClassMetaData> metas = new ArrayList<>(types.length); |
| for (Class<?> c : types) { |
| ClassMetaData meta = JPAFacadeHelper.getMetaData(emf, c); |
| if (meta != null) { |
| metas.add(meta); |
| } |
| } |
| clear(emf, false, metas.toArray(new ClassMetaData[metas.size()])); |
| } |
| |
| /** |
| * Delete all instances of the persistent types registered with the given factory using bulk delete queries, after |
| * first closing all open entity managers (and rolling back any open transactions). |
| */ |
| protected void clear(EntityManagerFactory emf) { |
| if (emf == null) { |
| return; |
| } |
| clear(emf, true, ((OpenJPAEntityManagerFactorySPI) emf).getConfiguration().getMetaDataRepositoryInstance() |
| .getMetaDatas()); |
| } |
| |
| /** |
| * Delete all instances of the given types using bulk delete queries. |
| * |
| * @param emf |
| * The EntityManagerFactory to use. A new EntityManager will be created from this EMF and used to execute |
| * bulk updates. |
| * @param closeEMs |
| * Whether any open EMs should be closed |
| * @param types |
| * the types that will be cleared. |
| */ |
| private void clear(EntityManagerFactory emf, boolean closeEMs, ClassMetaData... types) { |
| if (emf == null || types.length == 0) { |
| return; |
| } |
| |
| // prevent deadlock by closing the open entity managers |
| // and rolling back any open transactions |
| // before issuing delete statements on a new entity manager. |
| if (closeEMs) { |
| closeAllOpenEMs(emf); |
| } |
| if (retainDataOnTearDown) { |
| return; |
| } |
| EntityManager em = emf.createEntityManager(); |
| try { |
| em.getTransaction().begin(); |
| for (ClassMetaData meta : types) { |
| if (!meta.isMapped() || meta.isEmbeddedOnly() |
| || Modifier.isAbstract(meta.getDescribedType().getModifiers()) |
| && !isBaseManagedInterface(meta, types)) { |
| continue; |
| } |
| em.createQuery("DELETE FROM " + meta.getTypeAlias() + " o").executeUpdate(); |
| } |
| em.getTransaction().commit(); |
| } catch (Exception e) { |
| // ignore |
| } finally { |
| closeEM(em); |
| } |
| } |
| |
| protected DBDictionary getDbDictioary(EntityManagerFactory emf) { |
| return ((JDBCConfiguration)((OpenJPAEntityManagerFactory) emf).getConfiguration()).getDBDictionaryInstance(); |
| } |
| |
| |
| /** |
| * Return the entity name for the given type. |
| */ |
| protected String entityName(EntityManagerFactory emf, Class<?> c) { |
| ClassMetaData meta = JPAFacadeHelper.getMetaData(emf, c); |
| return (meta == null) ? null : meta.getTypeAlias(); |
| } |
| |
| /** |
| * Determines if the class associated with the provided {@link ClassMetaData} is a managed interface and does not |
| * extend another managed interface. |
| * |
| * @param meta |
| * {@link ClassMetaData} for the class to examine |
| * @param types |
| * array of class meta data for persistent types |
| * @return true if the {@link ClassMetaData} is for an interface and the interface does not extend another managed |
| * interface |
| */ |
| private boolean isBaseManagedInterface(ClassMetaData meta, ClassMetaData... types) { |
| |
| if (Modifier.isInterface(meta.getDescribedType().getModifiers()) && !isExtendedManagedInterface(meta, types)) { |
| return true; |
| } |
| return false; |
| } |
| |
| /** |
| * Determines if the class associated with the provided {@link ClassMetaData} is an interface and if it extends |
| * another managed interface. |
| * |
| * @param meta |
| * {@link ClassMetaData} for the class to examine |
| * @param types |
| * array of class meta data for persistent types |
| * @return true if the {@link ClassMetaData} is for an interface and the interface extends another managed interface |
| */ |
| private boolean isExtendedManagedInterface(ClassMetaData meta, ClassMetaData... types) { |
| |
| if (!Modifier.isInterface(meta.getDescribedType().getModifiers())) { |
| return false; |
| } |
| |
| // Run through the interface this class extends. If any of them |
| // are managed/have class metadata, return true. |
| Class<?>[] ifaces = meta.getDescribedType().getInterfaces(); |
| for (int i = 0; ifaces != null && i < ifaces.length; i++) { |
| for (ClassMetaData meta2 : types) { |
| if (ifaces[i].equals(meta2.getDescribedType())) { |
| return true; |
| } |
| } |
| } |
| return false; |
| } |
| |
| public static void assertNotEquals(Object o1, Object o2) { |
| if (o1 == o2) { |
| fail("expected args to be different; were the same instance."); |
| } else if (o1 == null || o2 == null) { |
| return; |
| } else if (o1.equals(o2)) { |
| fail("expected args to be different; compared equal."); |
| } |
| } |
| |
| /** |
| * Round-trip a serializable object to bytes. |
| */ |
| @SuppressWarnings("unchecked") |
| public static <T> T roundtrip(T o) throws ClassNotFoundException, IOException { |
| ByteArrayOutputStream bytes = new ByteArrayOutputStream(); |
| ObjectOutputStream out = new ObjectOutputStream(bytes); |
| out.writeObject(o); |
| out.flush(); |
| ObjectInputStream in = new ObjectInputStream(new ByteArrayInputStream(bytes.toByteArray())); |
| return (T) in.readObject(); |
| } |
| |
| // ================================================ |
| // Utility methods for exception handling |
| // ================================================ |
| /** |
| * Asserts that the given targetType is assignable from given actual Throwable. |
| */ |
| protected void assertException(final Throwable actual, Class<?> targetType) { |
| assertException(actual, targetType, null); |
| } |
| |
| /** |
| * Asserts that the given targetType is assignable from given actual Throwable. Asserts that the nestedType is |
| * nested (possibly recursively) within the given actual Throwable. |
| * |
| * @param actual |
| * is the actual throwable to be tested |
| * @param targetType |
| * is expected type or super type of actual. If null, then the check is omitted. |
| * @param nestedTargetType |
| * is expected type of exception nested within actual. If null this search is omitted. |
| * |
| */ |
| protected void assertException(final Throwable actual, Class<?> targetType, Class<?> nestedTargetType) { |
| assertNotNull(actual); |
| Class<?> actualType = actual.getClass(); |
| if (targetType != null && !targetType.isAssignableFrom(actualType)) { |
| actual.printStackTrace(); |
| fail(targetType.getName() + " is not assignable from " + actualType.getName()); |
| } |
| |
| if (nestedTargetType != null) { |
| Throwable nested = actual.getCause(); |
| Class<?> nestedActualType = (nested == null) ? null : nested.getClass(); |
| while (nestedActualType != null) { |
| if (nestedTargetType.isAssignableFrom(nestedActualType)) { |
| return; |
| } else { |
| Throwable next = nested.getCause(); |
| if (next == null || next == nested) { |
| break; |
| } |
| nestedActualType = next.getClass(); |
| nested = next; |
| } |
| } |
| actual.printStackTrace(); |
| fail("No nested type " + nestedTargetType + " in " + actual); |
| } |
| } |
| |
| /** |
| * Asserts that the given targetType is assignable from given actual Throwable and that the exception message |
| * contains the specified message or message fragments. |
| */ |
| protected void assertExceptionMessage(final Throwable actual, Class<?> targetType, String... messages) { |
| assertException(actual, targetType, null); |
| assertMessage(actual, messages); |
| } |
| |
| /** |
| * Assert that each of given keys are present in the message of the given Throwable. |
| */ |
| protected void assertMessage(Throwable actual, String... keys) { |
| if (actual == null || keys == null) { |
| return; |
| } |
| String message = actual.getMessage(); |
| for (String key : keys) { |
| assertTrue(key + " is not in " + message, message.contains(key)); |
| } |
| } |
| |
| public void printException(Throwable t) { |
| printException(t, 2); |
| } |
| |
| public void printException(Throwable t, int tab) { |
| if (t == null) { |
| return; |
| } |
| for (int i = 0; i < tab * 4; i++) { |
| System.out.print(" "); |
| } |
| String sqlState = |
| (t instanceof SQLException) ? "(SQLState=" + ((SQLException) t).getSQLState() + ":" + t.getMessage() + ")" |
| : ""; |
| System.out.println(t.getClass().getName() + sqlState); |
| if (t.getCause() == t) { |
| return; |
| } |
| printException(t.getCause(), tab + 2); |
| } |
| |
| /** |
| * Overrides to allow tests annotated with @AllowFailure to fail. |
| * If @DatabasePlatform value matches the current JDBC driver or |
| * tests have been disabled, then the test will not be run. |
| * If the test is in error then the normal pathway is executed. |
| */ |
| @Override |
| public void runBare() throws Throwable { |
| if (!isRunsOnCurrentPlatform()) { |
| return; |
| } |
| runBare(getAllowFailure()); |
| } |
| |
| protected void runBare(AllowFailure allowFailureAnnotation) throws Throwable { |
| boolean allowFailureValue = allowFailureAnnotation == null ? false : allowFailureAnnotation.value(); |
| |
| if (allowFailureValue) { |
| if (ALLOW_FAILURE_IGNORE.equalsIgnoreCase(allowFailureConfig)) { |
| return; // skip this test |
| } else { |
| try { |
| super.runBare(); |
| } catch (Throwable t) { |
| if (ALLOW_FAILURE_LOG.equalsIgnoreCase(allowFailureConfig)) { |
| System.err.println("*** FAILED (but ignored): " + this); |
| System.err.println("*** Reason : " + allowFailureAnnotation.message()); |
| System.err.println("Stacktrace of failure"); |
| t.printStackTrace(); |
| } else { |
| throw t; |
| } |
| } |
| } |
| } else { |
| super.runBare(); |
| } |
| } |
| |
| /** |
| * Override to run the test and assert its state. |
| * @exception Throwable if any exception is thrown |
| */ |
| @Override |
| protected void runTest() throws Throwable { |
| if (isTestsDisabled()) { |
| return; |
| } |
| super.runTest(); |
| } |
| |
| /** |
| * Affirms if the test case or the test method is annotated with |
| * |
| * @AllowFailure. Method level annotation has higher precedence than Class level annotation. |
| */ |
| protected AllowFailure getAllowFailure() { |
| try { |
| Method runMethod = getClass().getMethod(getName(), (Class[]) null); |
| AllowFailure anno = runMethod.getAnnotation(AllowFailure.class); |
| if (anno != null) { |
| return anno; |
| } |
| } catch (SecurityException | NoSuchMethodException e) { |
| // ignore |
| } |
| return getClass().getAnnotation(AllowFailure.class); |
| } |
| |
| /** |
| * Affirms if either this test has been annotated with @DatabasePlatform and at least one of the specified driver is |
| * available in the classpath, or no such annotation is used. |
| * |
| */ |
| protected boolean isRunsOnCurrentPlatform() { |
| DatabasePlatform anno = getClass().getAnnotation(DatabasePlatform.class); |
| if (anno == null) { |
| return true; |
| } |
| if (anno != null) { |
| String value = anno.value(); |
| if (value == null || value.trim().length() == 0) { |
| return true; |
| } |
| String[] drivers = value.split("\\,"); |
| for (String driver : drivers) { |
| try { |
| Class.forName(driver.trim(), false, Thread.currentThread().getContextClassLoader()); |
| return true; |
| } catch (Throwable t) { |
| // ignore |
| } |
| } |
| } |
| return false; |
| } |
| |
| /** |
| * Determines whether specified platform is the target database platform in use by the test framework. |
| * |
| * @param target |
| * platform name (derby, db2, oracle, etc.) |
| * @return true if the specified platform matches the platform in use |
| */ |
| public boolean isTargetPlatform(String target) { |
| String url = getPlatform(); |
| return url != null && url.indexOf(target) != -1; |
| } |
| |
| /** |
| * Returns the platform in use by the test framework |
| * |
| * @return the database platform |
| */ |
| public String getPlatform() { |
| return System.getProperty("platform", "derby"); |
| } |
| |
| /** |
| * Assert whether the Cache contains an instance of the specified class and id. |
| * |
| * @param cache |
| * The JPA Cache to verify |
| * @param clss |
| * The Entity type |
| * @param id |
| * ID of the entity |
| * @param expected |
| * Whether the class should be found in the cache |
| */ |
| protected void assertCached(Cache cache, Class<?> clss, Object id, boolean expected) { |
| if (expected) { |
| assertTrue(String.format("Expected %s:%s to exist in cache", clss, id), cache.contains(clss, id)); |
| } else { |
| assertFalse(String.format("Expected %s:%s not to exist in cache", clss, id), cache.contains(clss, id)); |
| } |
| } |
| |
| protected void setTestsDisabled(boolean disable) { |
| synchronized (testsDisabled) { |
| testsDisabled = disable; |
| } |
| } |
| |
| protected boolean isTestsDisabled() { |
| synchronized (testsDisabled) { |
| return testsDisabled; |
| } |
| } |
| |
| protected Class<?> resolveEntityClass(JPAEntityClassEnum enumerationRef) |
| throws ClassNotFoundException |
| { |
| if (enumerationRef == null) |
| { |
| throw new IllegalArgumentException("Null value passed into the constructNewEntityObject method."); |
| } |
| String className = enumerationRef.getEntityClassName(); |
| if (className == null) |
| { |
| throw new IllegalArgumentException("Enumeration toString() method implementation returned a null value."); |
| } |
| |
| return Class.forName(className); |
| } |
| |
| protected Object constructNewEntityObject(JPAEntityClassEnum enumerationRef) |
| throws ClassNotFoundException, SecurityException, NoSuchMethodException, |
| IllegalArgumentException, InstantiationException, |
| IllegalAccessException, InvocationTargetException |
| { |
| Class<?> classType = resolveEntityClass(enumerationRef); |
| Class<?> constructorArgSig[] = new Class[] {}; |
| Object constructorArgs[] = new Object[] {}; |
| |
| Constructor<?> classConstructor = classType.getConstructor(constructorArgSig); |
| Object newEntity = classConstructor.newInstance(constructorArgs); |
| |
| return newEntity; |
| } |
| |
| protected Object constructNewEntityObject(Class<?> entityClass) |
| throws SecurityException, NoSuchMethodException, |
| IllegalArgumentException, InstantiationException, |
| IllegalAccessException, InvocationTargetException |
| { |
| Class<?> constructorArgSig[] = new Class[] {}; |
| Object constructorArgs[] = new Object[] {}; |
| |
| Constructor<?> classConstructor = entityClass.getConstructor(constructorArgSig); |
| Object newEntity = classConstructor.newInstance(constructorArgs); |
| |
| return newEntity; |
| } |
| |
| } |