Example usage for org.springframework.orm.jpa.persistenceunit MutablePersistenceUnitInfo getClass

List of usage examples for org.springframework.orm.jpa.persistenceunit MutablePersistenceUnitInfo getClass

Introduction

In this page you can find the example usage for org.springframework.orm.jpa.persistenceunit MutablePersistenceUnitInfo getClass.

Prototype

@HotSpotIntrinsicCandidate
public final native Class<?> getClass();

Source Link

Document

Returns the runtime class of this Object .

Usage

From source file:org.broadleafcommerce.common.extensibility.jpa.MergePersistenceUnitManager.java

@Override
@SuppressWarnings({ "unchecked", "ToArrayCallWithZeroLengthArrayArgument" })
public void preparePersistenceUnitInfos() {
    //Need to use reflection to try and execute the logic in the DefaultPersistenceUnitManager
    //SpringSource added a block of code in version 3.1 to "protect" the user from having more than one PU with
    //the same name.  Of course, in our case, this happens before a merge occurs.  They have added
    //a block of code to throw an exception if more than one PU has the same name.  We want to
    //use the logic of the DefaultPersistenceUnitManager without the exception in the case of
    //a duplicate name. This will require reflection in order to do what we need.
    try {//  w  ww  . j a va2 s.  c  om
        Set<String> persistenceUnitInfoNames = null;
        Map<String, PersistenceUnitInfo> persistenceUnitInfos = null;
        ResourcePatternResolver resourcePatternResolver = null;
        Field[] fields = getClass().getSuperclass().getDeclaredFields();
        for (Field field : fields) {
            if ("persistenceUnitInfoNames".equals(field.getName())) {
                field.setAccessible(true);
                persistenceUnitInfoNames = (Set<String>) field.get(this);
            } else if ("persistenceUnitInfos".equals(field.getName())) {
                field.setAccessible(true);
                persistenceUnitInfos = (Map<String, PersistenceUnitInfo>) field.get(this);
            } else if ("resourcePatternResolver".equals(field.getName())) {
                field.setAccessible(true);
                resourcePatternResolver = (ResourcePatternResolver) field.get(this);
            }
        }

        persistenceUnitInfoNames.clear();
        persistenceUnitInfos.clear();

        Method readPersistenceUnitInfos = getClass().getSuperclass()
                .getDeclaredMethod("readPersistenceUnitInfos");
        readPersistenceUnitInfos.setAccessible(true);

        //In Spring 3.0 this returns an array
        //In Spring 3.1 this returns a List
        Object pInfosObject = readPersistenceUnitInfos.invoke(this);
        Object[] puis;
        if (pInfosObject.getClass().isArray()) {
            puis = (Object[]) pInfosObject;
        } else {
            puis = ((Collection) pInfosObject).toArray();
        }

        for (Object pui : puis) {
            MutablePersistenceUnitInfo mPui = (MutablePersistenceUnitInfo) pui;
            if (mPui.getPersistenceUnitRootUrl() == null) {
                Method determineDefaultPersistenceUnitRootUrl = getClass().getSuperclass()
                        .getDeclaredMethod("determineDefaultPersistenceUnitRootUrl");
                determineDefaultPersistenceUnitRootUrl.setAccessible(true);
                mPui.setPersistenceUnitRootUrl((URL) determineDefaultPersistenceUnitRootUrl.invoke(this));
            }
            ConfigurationOnlyState state = ConfigurationOnlyState.getState();
            if ((state == null || !state.isConfigurationOnly()) && mPui.getNonJtaDataSource() == null) {
                mPui.setNonJtaDataSource(getDefaultDataSource());
            }
            if (super.getLoadTimeWeaver() != null) {
                Method puiInitMethod = mPui.getClass().getDeclaredMethod("init", LoadTimeWeaver.class);
                puiInitMethod.setAccessible(true);
                puiInitMethod.invoke(pui, getLoadTimeWeaver());
            } else {
                Method puiInitMethod = mPui.getClass().getDeclaredMethod("init", ClassLoader.class);
                puiInitMethod.setAccessible(true);
                puiInitMethod.invoke(pui, resourcePatternResolver.getClassLoader());
            }
            postProcessPersistenceUnitInfo((MutablePersistenceUnitInfo) pui);
            String name = mPui.getPersistenceUnitName();
            persistenceUnitInfoNames.add(name);

            persistenceUnitInfos.put(name, mPui);
        }
    } catch (Exception e) {
        throw new RuntimeException("An error occured reflectively invoking methods on " + "class: "
                + getClass().getSuperclass().getName(), e);
    }

    try {
        List<String> managedClassNames = new ArrayList<String>();

        boolean weaverRegistered = true;
        for (PersistenceUnitInfo pui : mergedPus.values()) {
            for (BroadleafClassTransformer transformer : classTransformers) {
                try {
                    if (!(transformer instanceof NullClassTransformer)
                            && pui.getPersistenceUnitName().equals("blPU")) {
                        pui.addTransformer(transformer);
                    }
                } catch (Exception e) {
                    Exception refined = ExceptionHelper.refineException(IllegalStateException.class,
                            RuntimeException.class, e);
                    if (refined instanceof IllegalStateException) {
                        LOG.warn(
                                "A BroadleafClassTransformer is configured for this persistence unit, but Spring "
                                        + "reported a problem (likely that a LoadTimeWeaver is not registered). As a result, "
                                        + "the Broadleaf Commerce ClassTransformer ("
                                        + transformer.getClass().getName() + ") is "
                                        + "not being registered with the persistence unit.");
                        weaverRegistered = false;
                    } else {
                        throw refined;
                    }
                }
            }
        }

        // Only validate transformation results if there was a LoadTimeWeaver registered in the first place
        if (weaverRegistered) {
            for (PersistenceUnitInfo pui : mergedPus.values()) {
                for (String managedClassName : pui.getManagedClassNames()) {
                    if (!managedClassNames.contains(managedClassName)) {
                        // Force-load this class so that we are able to ensure our instrumentation happens globally.
                        // If transformation is happening, it should be tracked in EntityMarkerClassTransformer
                        Class.forName(managedClassName, true, getClass().getClassLoader());
                        managedClassNames.add(managedClassName);
                    }
                }
            }

            // If a class happened to be loaded by the ClassLoader before we had a chance to set up our instrumentation,
            // it may not be in a consistent state. This verifies with the EntityMarkerClassTransformer that it
            // actually saw the classes loaded by the above process
            List<String> nonTransformedClasses = new ArrayList<String>();
            for (PersistenceUnitInfo pui : mergedPus.values()) {
                for (String managedClassName : pui.getManagedClassNames()) {
                    // We came across a class that is not a real persistence class (doesn't have the right annotations)
                    // but is still being transformed/loaded by
                    // the persistence unit. This might have unexpected results downstream, but it could also be benign
                    // so just output a warning
                    if (entityMarkerClassTransformer.getTransformedNonEntityClassNames()
                            .contains(managedClassName)) {
                        LOG.warn("The class " + managedClassName
                                + " is marked as a managed class within the MergePersistenceUnitManager"
                                + " but is not annotated with @Entity, @MappedSuperclass or @Embeddable."
                                + " This class is still referenced in a persistence.xml and is being transformed by"
                                + " PersistenceUnit ClassTransformers which may result in problems downstream"
                                + " and represents a potential misconfiguration. This class should be removed from"
                                + " your persistence.xml");
                    } else if (!entityMarkerClassTransformer.getTransformedEntityClassNames()
                            .contains(managedClassName)) {
                        // This means the class not in the 'warning' list, but it is also not in the list that we would
                        // expect it to be in of valid entity classes that were transformed. This means that we
                        // never got the chance to transform the class AT ALL even though it is a valid entity class
                        nonTransformedClasses.add(managedClassName);
                    }
                }
            }

            if (CollectionUtils.isNotEmpty(nonTransformedClasses)) {
                String message = "The classes\n" + Arrays.toString(nonTransformedClasses.toArray())
                        + "\nare managed classes within the MergePersistenceUnitManager"
                        + "\nbut were not detected as being transformed by the EntityMarkerClassTransformer. These"
                        + "\nclasses are likely loaded earlier in the application startup lifecyle by the servlet"
                        + "\ncontainer. Verify that an empty <absolute-ordering /> element is contained in your"
                        + "\nweb.xml to disable scanning for ServletContainerInitializer classes by your servlet"
                        + "\ncontainer which can trigger early class loading. If the problem persists, ensure that"
                        + "\nthere are no bean references to your entity class anywhere else in your Spring applicationContext"
                        + "\nand consult the documentation for your servlet container to determine if classes are loaded"
                        + "\nprior to the Spring context initialization. Finally, ensure that Session Persistence is"
                        + "\nalso disabled by your Servlet Container. To do this in Tomcat, add <Manager pathname=\"\" />"
                        + "\ninside of the <Context> element in context.xml in your app's META-INF folder or your server's conf folder";
                LOG.error(message);
                throw new IllegalStateException(message);
            }
        }
    } catch (Exception e) {
        throw new RuntimeException(e);
    }
}