@SuppressWarnings("unchecked") @Override public void modifying(ScalarEvent e) { FrozenLazyInitializerImpl declaring = FrozenLazyInitializerImpl.this; if (!declaring.disableTargetListener) { ObjectModelFactory<ObjectModel> omFactory = declaring.omFactory; LazyInitializer rawLazyInitializer = declaring.lazyInitializer; EventAttributeContext localAttributeContext = e.getAttributeContext(AttributeScope.LOCAL); if (rawLazyInitializer.isUninitialized() || omFactory.get(rawLazyInitializer.getImplementation()) != e.getSource()) { ((ObjectModel) e.getSource()).removeScalarListener(this); return; } localAttributeContext.addAttribute(AK_MODIFIYING_EXECUTED, true); if (e.getProperty() == declaring.objectModelMetadata.getEntityIdProperty()) { FrozenContext<Object> ctx = (FrozenContext<Object>) declaring.idFrozenContext; localAttributeContext.addAttribute(AK_FROZENCONTEXT, ctx); FrozenContext.suspendFreezing(ctx, declaring.owner); } ScalarListener scalarListener = declaring.scalarListener; if (scalarListener != null) { declaring.executeModifying(e.dispatch(declaring.omFactory.get(declaring.owner))); } } }
private EntityPersister guessEntityPersister(Object object) { if (scope == null) { return null; } String entityName = null; // this code is largely copied from Session's bestGuessEntityName Object entity = object; if (entity instanceof HibernateProxy) { final LazyInitializer initializer = ((HibernateProxy) entity).getHibernateLazyInitializer(); if (initializer.isUninitialized()) { entityName = initializer.getEntityName(); } entity = initializer.getImplementation(); } if (entityName == null) { for (EntityNameResolver resolver : scope.resolveFactory().iterateEntityNameResolvers()) { entityName = resolver.resolveEntityName(entity); if (entityName != null) { break; } } } if (entityName == null) { // the old-time stand-by... entityName = object.getClass().getName(); } return scope.resolveFactory().getEntityPersister(entityName); }
/** * Pega o objeto real que esta sendo utilizado. Isto é necessário pois o hibernate empacota alguns * objetos em proxies. * * @param example o exemplo do bean que será utilizado na conversão * @return o objeto real que esta sendo utilizado */ public static Object getBean(Object example) { if (example instanceof HibernateProxy) { HibernateProxy proxy = (HibernateProxy) example; LazyInitializer initializer = proxy.getHibernateLazyInitializer(); // este código é soh para garantir que não vai dar um lazy initialization. SessionImplementor implementor = initializer.getSession(); if (initializer.isUninitialized()) { try { // getImplementation is going to want to talk to a session if (implementor.isClosed()) { // Give up and return example.getClass(); return example; } } catch (NoSuchMethodError ex) { // We must be using Hibernate 3.0/3.1 which doesn't have // this method } } return initializer.getImplementation(); } else { return example; } }
/** * 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; } }
/** Associate a proxy that was instantiated by another session with this session */ private void reassociateProxy(LazyInitializer li, HibernateProxy proxy) throws HibernateException { if (li.getSession() != this) { EntityPersister persister = session.getFactory().getEntityPersister(li.getEntityName()); EntityKey key = new EntityKey(li.getIdentifier(), persister, session.getEntityMode()); if (!proxiesByKey.containsKey(key)) proxiesByKey.put(key, proxy); // any earlier proxy takes precedence proxy.getHibernateLazyInitializer().setSession(session); } }
/** * If a deleted entity instance is re-saved, and it has a proxy, we need to reset the identifier * of the proxy */ public void reassociateProxy(Object value, Serializable id) throws MappingException { if (value instanceof ElementWrapper) { value = ((ElementWrapper) value).getElement(); } if (value instanceof HibernateProxy) { if (log.isDebugEnabled()) log.debug("setting proxy identifier: " + id); HibernateProxy proxy = (HibernateProxy) value; LazyInitializer li = proxy.getHibernateLazyInitializer(); li.setIdentifier(id); reassociateProxy(li, proxy); } }
/** * Possibly unproxy the given reference and reassociate it with the current session. * * @param maybeProxy The reference to be unproxied if it currently represents a proxy. * @return The unproxied instance. * @throws HibernateException */ public Object unproxyAndReassociate(Object maybeProxy) throws HibernateException { if (maybeProxy instanceof ElementWrapper) { maybeProxy = ((ElementWrapper) maybeProxy).getElement(); } if (maybeProxy instanceof HibernateProxy) { HibernateProxy proxy = (HibernateProxy) maybeProxy; LazyInitializer li = proxy.getHibernateLazyInitializer(); reassociateProxy(li, proxy); return li.getImplementation(); // initialize + unwrap the object } else { return maybeProxy; } }
@Test public void shouldRunHibernateLazyInitialization() throws Exception { LazyInitializer initializer = mock(LazyInitializer.class); SomeProxy proxy = new SomeProxy(initializer); proxy.name = "my name"; proxy.aField = "abc"; when(initializer.getPersistentClass()).thenReturn(Client.class); when(proxy.getHibernateLazyInitializer().getImplementation()).thenReturn(proxy); serialization.from(proxy).serialize(); assertThat(result(), is("{\"client\":{\"aField\":\"abc\",\"name\":\"my name\"}}")); }
/** Given that there is a pre-existing proxy. Initialize it if necessary; narrow if necessary. */ private Object returnNarrowedProxy( final LoadEvent event, final EntityPersister persister, final EntityKey keyToLoad, final LoadEventListener.LoadType options, final PersistenceContext persistenceContext, final Object proxy) { log.trace("entity proxy found in session cache"); LazyInitializer li = ((HibernateProxy) proxy).getHibernateLazyInitializer(); if (li.isUnwrap()) { return li.getImplementation(); } // return existing or narrowed proxy Object impl = options.isAllowProxyCreation() ? null : load(event, persister, keyToLoad, options); return persistenceContext.narrowProxy(proxy, persister, keyToLoad, impl); }
/** * Get the entity instance underlying the given proxy, throwing an exception if the proxy is * uninitialized. If the given object is not a proxy, simply return the argument. */ public Object unproxy(Object maybeProxy) throws HibernateException { if (maybeProxy instanceof ElementWrapper) { maybeProxy = ((ElementWrapper) maybeProxy).getElement(); } if (maybeProxy instanceof HibernateProxy) { HibernateProxy proxy = (HibernateProxy) maybeProxy; LazyInitializer li = proxy.getHibernateLazyInitializer(); if (li.isUninitialized()) { throw new PersistentObjectException( "object was an uninitialized proxy for " + li.getEntityName()); } return li.getImplementation(); // unwrap the object } else { return maybeProxy; } }
@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); } } }
/** * Check if the property is initialized. If the named property does not exist or is not * persistent, this method always returns <tt>true</tt>. * * @param proxy The potential proxy * @param propertyName the name of a persistent attribute of the object * @return true if the named property of the object is not listed as uninitialized; false * otherwise */ public static boolean isPropertyInitialized(Object proxy, String propertyName) { Object entity; if (proxy instanceof HibernateProxy) { LazyInitializer li = ((HibernateProxy) proxy).getHibernateLazyInitializer(); if (li.isUninitialized()) { return false; } else { entity = li.getImplementation(); } } else { entity = proxy; } if (FieldInterceptionHelper.isInstrumented(entity)) { FieldInterceptor interceptor = FieldInterceptionHelper.extractFieldInterceptor(entity); return interceptor == null || interceptor.isInitialized(propertyName); } else { return true; } }
protected Class<?> getClass(ExtendedObjectOutput out, Object v) { Class<?> cls = v.getClass(); if (v instanceof HibernateProxy) { LazyInitializer initializer = ((HibernateProxy) v).getHibernateLazyInitializer(); String className = (initializer.isUninitialized() ? initializer.getEntityName() : initializer.getImplementation().getClass().getName()); if (className != null && className.length() > 0) { try { cls = out.getReflection().loadClass(className); } catch (ClassNotFoundException e) { cls = initializer.getPersistentClass(); } } } return cls; }
@SuppressWarnings("unchecked") private void initTransient(Class<?> persistentClass) { LazyInitializer rawLazyInitializer = this.lazyInitializer; if (persistentClass == null) { persistentClass = getPersistentClass((BasicLazyInitializer) rawLazyInitializer); } HibernateObjectModelMetadata objectModelMetadata = HibernateMetadatas.of(persistentClass); this.objectModelMetadata = objectModelMetadata; this.omFactory = (ObjectModelFactory<ObjectModel>) ObjectModelFactoryFactory.factoryOf(objectModelMetadata.getObjectModelClass()); try { this.getIdentifierMethod = (Method) GET_IDENTIFIER_METHOD_FIELD.get(rawLazyInitializer); this.setIdentifierMethod = (Method) SET_IDENTIFIER_METHOD_FIELD.get(rawLazyInitializer); } catch (IllegalArgumentException | IllegalAccessException e) { throw new AssertionError(); } if (!rawLazyInitializer.isUninitialized()) { ObjectModel targetOM = this.omFactory.get(rawLazyInitializer.getImplementation()); ScalarListener listener = this.new TargetScalarListener(); targetOM.removeScalarListener(listener); targetOM.addScalarListener(listener); } }
/** * @param proxy * @return * @throws ClassNotFoundException */ public static Object loadLazyObject(HibernateProxy proxy) throws ClassNotFoundException { LazyInitializer init = proxy.getHibernateLazyInitializer(); logger.debug(init.getEntityName() + StringUtils.SPACE + init.getIdentifier()); return HibernateUtil.getObject(Class.forName(init.getEntityName()), init.getIdentifier()); }