/** * If the existing proxy is insufficiently "narrow" (derived), instantiate a new proxy and * overwrite the registration of the old one. This breaks == and occurs only for "class" proxies * rather than "interface" proxies. Also init the proxy to point to the given target * implementation if necessary. * * @param proxy The proxy instance to be narrowed. * @param persister The persister for the proxied entity. * @param key The internal cache key for the proxied entity. * @param object (optional) the actual proxied entity instance. * @return An appropriately narrowed instance. * @throws HibernateException */ public Object narrowProxy(Object proxy, EntityPersister persister, EntityKey key, Object object) throws HibernateException { boolean alreadyNarrow = persister.getConcreteProxyClass(session.getEntityMode()).isAssignableFrom(proxy.getClass()); if (!alreadyNarrow) { if (PROXY_WARN_LOG.isWarnEnabled()) { PROXY_WARN_LOG.warn( "Narrowing proxy to " + persister.getConcreteProxyClass(session.getEntityMode()) + " - this operation breaks =="); } if (object != null) { proxiesByKey.remove(key); return object; // return the proxied object } else { proxy = persister.createProxy(key.getIdentifier(), session); proxiesByKey.put(key, proxy); // overwrite old proxy return proxy; } } else { if (object != null) { LazyInitializer li = ((HibernateProxy) proxy).getHibernateLazyInitializer(); li.setImplementation(object); } return proxy; } }
@Override public void setImplementation(Object target) { LazyInitializer rawLazyInitializer = this.lazyInitializer; Object oldTarget = rawLazyInitializer.isUninitialized() ? null : rawLazyInitializer.getImplementation(); if (target != oldTarget) { ScalarListener listener = this.new TargetScalarListener(); if (oldTarget != null) { this.omFactory.get(oldTarget).removeScalarListener(listener); } rawLazyInitializer.setImplementation(target); this.oldTarget = target; if (target != null) { ObjectModel targetOM = this.omFactory.get(target); targetOM.removeScalarListener(listener); // remove the duplicated listener. targetOM.addScalarListener(listener); } } }