List of usage examples for org.springframework.orm.jpa.persistenceunit MutablePersistenceUnitInfo setPersistenceUnitRootUrl
public void setPersistenceUnitRootUrl(@Nullable URL persistenceUnitRootUrl)
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);
}
}