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

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

Introduction

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

Prototype

public void setPersistenceUnitRootUrl(@Nullable URL persistenceUnitRootUrl) 

Source Link

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 {/*from  ww  w  .  j  a v a 2s . 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);
    }
}