diff --git a/openjpa-kernel/src/main/java/org/apache/openjpa/util/ProxyManagerImpl.java b/openjpa-kernel/src/main/java/org/apache/openjpa/util/ProxyManagerImpl.java index 536edcec1..9a2d75cef 100644 --- a/openjpa-kernel/src/main/java/org/apache/openjpa/util/ProxyManagerImpl.java +++ b/openjpa-kernel/src/main/java/org/apache/openjpa/util/ProxyManagerImpl.java @@ -93,10 +93,15 @@ public class ProxyManagerImpl _stdMaps.put(SortedMap.class, TreeMap.class); } + private final Set _unproxyable = new HashSet(); private final Map _proxies = new ConcurrentHashMap(); private boolean _trackChanges = true; private boolean _assertType = false; + public ProxyManagerImpl() { + _unproxyable.add(TimeZone.class.getName()); + } + /** * Whether proxies produced by this factory will use {@link ChangeTracker}s * to try to cut down on data store operations at the cost of some extra @@ -133,6 +138,24 @@ public class ProxyManagerImpl _assertType = assertType; } + /** + * Return a mutable view of class names we know cannot be proxied + * correctly by this manager. + */ + public Collection getUnproxyable() { + return _unproxyable; + } + + /** + * Provided for auto-configuration. Add the given semicolon-separated + * class names to the set of class names we know cannot be proxied correctly + * by this manager. + */ + public void setUnproxyable(String clsNames) { + if (clsNames != null) + _unproxyable.addAll(Arrays.asList(Strings.split(clsNames, ";", 0))); + } + public Object copyArray(Object orig) { if (orig == null) return null; @@ -398,8 +421,11 @@ public class ProxyManagerImpl * Return the cached factory proxy for the given bean type. */ private ProxyBean getFactoryProxyBean(Object orig) { - // we don't lock here; ok if two proxies get generated for same type Class type = orig.getClass(); + if (isUnproxyable(type)) + return null; + + // we don't lock here; ok if two proxies get generated for same type ProxyBean proxy = (ProxyBean) _proxies.get(type); if (proxy == null && !_proxies.containsKey(type)) { ClassLoader l = getMostDerivedLoader(type, ProxyBean.class); @@ -417,6 +443,18 @@ public class ProxyManagerImpl return proxy; } + /** + * Return whether the given type is known to be unproxyable. + */ + protected boolean isUnproxyable(Class type) { + for (; type != null && type != Object.class; + type = type.getSuperclass()) { + if (_unproxyable.contains(type.getName())) + return true; + } + return false; + } + /** * Load the proxy class generated at build time for the given type, * returning null if none exists.