/// <summary> /// Check if the property is initialized. If the named property does not exist /// or is not persistent, this method always returns <tt>true</tt>. /// </summary> /// <param name="proxy">The potential proxy </param> /// <param name="propertyName">the name of a persistent attribute of the object </param> /// <returns> /// true if the named property of the object is not listed as uninitialized; /// false if the object is an uninitialized proxy, or the named property is uninitialized /// </returns> public static bool IsPropertyInitialized(object proxy, string propertyName) { object entity; if (proxy is INHibernateProxy) { ILazyInitializer li = ((INHibernateProxy)proxy).HibernateLazyInitializer; if (li.IsUninitialized) { return(false); } else { entity = li.GetImplementation(); } } else { entity = proxy; } if (FieldInterceptionHelper.IsInstrumented(entity)) { IFieldInterceptor interceptor = FieldInterceptionHelper.ExtractFieldInterceptor(entity); return(interceptor == null || interceptor.IsInitializedField(propertyName)); } else { return(true); } }
/// <summary> /// Check for a <see cref="PersistentClass"/> if is enhanced for lazy loading. /// NOTE: The logic was taken from <see cref="EntityMetamodel"/>. /// </summary> /// <param name="persistentClass">The persistent class to check.</param> /// <returns>Whether the persistent class is enhanced for lazy loading or not.</returns> private static bool IsEnhancedForLazyLoading(PersistentClass persistentClass) { var lazyAvailable = persistentClass.HasPocoRepresentation && FieldInterceptionHelper.IsInstrumented(persistentClass.MappedClass); var lazy = persistentClass.IsLazy && (!persistentClass.HasPocoRepresentation || !ReflectHelper.IsFinalClass(persistentClass.ProxyInterface)); lazyAvailable &= lazy; if (!lazyAvailable) { return(false); } foreach (var prop in persistentClass.PropertyIterator) { // NH: A lazy property is a simple property marked with lazy=true var islazyProperty = prop.IsLazy && (!prop.IsEntityRelation || prop.UnwrapProxy); // NH: A Relation (in this case many-to-one or one-to-one) marked as "no-proxy" var isUnwrapProxy = prop.UnwrapProxy; if (islazyProperty || isUnwrapProxy) { return(true); } } return(false); }
public bool RequiresDirtyCheck(object entity) { return (IsModifiableEntity() && (Persister.HasMutableProperties || !FieldInterceptionHelper.IsInstrumented(entity) || FieldInterceptionHelper.ExtractFieldInterceptor(entity).IsDirty)); }
private void MarkInterceptorDirty(object entity, IEntityPersister persister, IEventSource source) { if (FieldInterceptionHelper.IsInstrumented(entity)) { IFieldInterceptor interceptor = FieldInterceptionHelper.InjectFieldInterceptor(entity, persister.EntityName, persister.GetMappedClass(source.EntityMode), null, null, source); interceptor.MarkDirty(); } }
public bool RequiresDirtyCheck(object entity) { bool isMutableInstance = status != Status.ReadOnly && persister.IsMutable; return (isMutableInstance && (Persister.HasMutableProperties || !FieldInterceptionHelper.IsInstrumented(entity) || FieldInterceptionHelper.ExtractFieldInterceptor(entity).IsDirty)); }
private void MarkInterceptorDirty(object entity, object target) { if (FieldInterceptionHelper.IsInstrumented(entity)) { IFieldInterceptor interceptor = FieldInterceptionHelper.ExtractFieldInterceptor(target); if (interceptor != null) { interceptor.MarkDirty(); } } }
public static bool IsPropertyInitialized(object proxy, string propertyName) { object entity; if (!IsProxyFactoryConfigurated()) { //if the proxy provider it's not configurated, can't be a proxy neither an instrumented field. return(true); } if (proxy.IsProxy()) { ILazyInitializer li = ((INHibernateProxy)proxy).HibernateLazyInitializer; if (li.IsUninitialized) { return(false); } else { entity = li.GetImplementation(); } } else { entity = proxy; } if (FieldInterceptionHelper.IsInstrumented(entity)) { IFieldInterceptor interceptor = FieldInterceptionHelper.ExtractFieldInterceptor(entity); return(interceptor == null || interceptor.IsInitializedField(propertyName)); } else { return(true); } }
public async Task LazyPropertyShouldBeUninitializedAndLoadableAsync() { using (var session = OpenSession()) using (var tran = session.BeginTransaction()) { var e1 = await(session.Query <CompositeEntity>().SingleAsync()); Assert.Multiple( () => { Assert.That( NHibernateUtil.IsPropertyInitialized(e1, nameof(CompositeEntity.LazyProperty)), Is.False, "Lazy property initialization status"); Assert.That( FieldInterceptionHelper.IsInstrumented(e1), Is.True, "Entity IsInstrumented"); Assert.That( e1, Has.Property(nameof(CompositeEntity.LazyProperty)).EqualTo("LazyProperty")); }); await(tran.CommitAsync()); } }
public void LazyPropertyShouldBeUninitializedAndLoadableWithComponentId() { using (var session = OpenSession()) using (var tran = session.BeginTransaction()) { var e2 = session.Query <EntityWithComponentId>().Single(); Assert.Multiple( () => { Assert.That( NHibernateUtil.IsPropertyInitialized(e2, nameof(CompositeEntity.LazyProperty)), Is.False, "Lazy property initialization status"); Assert.That( FieldInterceptionHelper.IsInstrumented(e2), Is.True, "Entity IsInstrumented"); Assert.That( e2, Has.Property(nameof(CompositeEntity.LazyProperty)).EqualTo("LazyProperty")); }); tran.Commit(); } }
public EntityMetamodel(PersistentClass persistentClass, ISessionFactoryImplementor sessionFactory) { this.sessionFactory = sessionFactory; name = persistentClass.EntityName; rootName = persistentClass.RootClazz.EntityName; entityType = TypeFactory.ManyToOne(name); type = persistentClass.MappedClass; rootType = persistentClass.RootClazz.MappedClass; rootTypeAssemblyQualifiedName = rootType == null ? null : rootType.AssemblyQualifiedName; identifierProperty = PropertyFactory.BuildIdentifierProperty(persistentClass, sessionFactory.GetIdentifierGenerator(rootName)); versioned = persistentClass.IsVersioned; bool lazyAvailable = persistentClass.HasPocoRepresentation && FieldInterceptionHelper.IsInstrumented(persistentClass.MappedClass); bool hasLazy = false; propertySpan = persistentClass.PropertyClosureSpan; properties = new StandardProperty[propertySpan]; List<int> naturalIdNumbers = new List<int>(); #region temporary propertyNames = new string[propertySpan]; propertyTypes = new IType[propertySpan]; propertyUpdateability = new bool[propertySpan]; propertyInsertability = new bool[propertySpan]; insertInclusions = new ValueInclusion[propertySpan]; updateInclusions = new ValueInclusion[propertySpan]; nonlazyPropertyUpdateability = new bool[propertySpan]; propertyCheckability = new bool[propertySpan]; propertyNullability = new bool[propertySpan]; propertyVersionability = new bool[propertySpan]; propertyLaziness = new bool[propertySpan]; cascadeStyles = new CascadeStyle[propertySpan]; #endregion int i = 0; int tempVersionProperty = NoVersionIndex; bool foundCascade = false; bool foundCollection = false; bool foundMutable = false; bool foundInsertGeneratedValue = false; bool foundUpdateGeneratedValue = false; bool foundNonIdentifierPropertyNamedId = false; foreach (Mapping.Property prop in persistentClass.PropertyClosureIterator) { if (prop == persistentClass.Version) { tempVersionProperty = i; properties[i] = PropertyFactory.BuildVersionProperty(prop, lazyAvailable); } else { properties[i] = PropertyFactory.BuildStandardProperty(prop, lazyAvailable); } if (prop.IsNaturalIdentifier) { naturalIdNumbers.Add(i); } if ("id".Equals(prop.Name)) { foundNonIdentifierPropertyNamedId = true; } #region temporary bool lazyProperty = prop.IsLazy && lazyAvailable; if (lazyProperty) hasLazy = true; propertyLaziness[i] = lazyProperty; propertyNames[i] = properties[i].Name; propertyTypes[i] = properties[i].Type; propertyNullability[i] = properties[i].IsNullable; propertyUpdateability[i] = properties[i].IsUpdateable; propertyInsertability[i] = properties[i].IsInsertable; insertInclusions[i] = DetermineInsertValueGenerationType(prop, properties[i]); updateInclusions[i] = DetermineUpdateValueGenerationType(prop, properties[i]); propertyVersionability[i] = properties[i].IsVersionable; nonlazyPropertyUpdateability[i] = properties[i].IsUpdateable && !lazyProperty; propertyCheckability[i] = propertyUpdateability[i] || (propertyTypes[i].IsAssociationType && ((IAssociationType) propertyTypes[i]).IsAlwaysDirtyChecked); cascadeStyles[i] = properties[i].CascadeStyle; #endregion if (properties[i].IsLazy) { hasLazy = true; } if (properties[i].CascadeStyle != CascadeStyle.None) { foundCascade = true; } if (IndicatesCollection(properties[i].Type)) { foundCollection = true; } if (propertyTypes[i].IsMutable && propertyCheckability[i]) { foundMutable = true; } if (insertInclusions[i] != ValueInclusion.None) { foundInsertGeneratedValue = true; } if (updateInclusions[i] != ValueInclusion.None) { foundUpdateGeneratedValue = true; } MapPropertyToIndex(prop, i); i++; } if (naturalIdNumbers.Count == 0) naturalIdPropertyNumbers = null; else naturalIdPropertyNumbers = naturalIdNumbers.ToArray(); hasCascades = foundCascade; hasInsertGeneratedValues = foundInsertGeneratedValue; hasUpdateGeneratedValues = foundUpdateGeneratedValue; hasNonIdentifierPropertyNamedId = foundNonIdentifierPropertyNamedId; versionPropertyIndex = tempVersionProperty; hasLazyProperties = hasLazy; if (hasLazyProperties) log.Info("lazy property fetching available for: " + name); lazy = persistentClass.IsLazy && (!persistentClass.HasPocoRepresentation || !ReflectHelper.IsFinalClass(persistentClass.ProxyInterface)); mutable = persistentClass.IsMutable; if (!persistentClass.IsAbstract.HasValue) { // legacy behavior (with no abstract attribute specified) isAbstract = persistentClass.HasPocoRepresentation && ReflectHelper.IsAbstractClass(persistentClass.MappedClass); } else { isAbstract = persistentClass.IsAbstract.Value; if (!isAbstract && persistentClass.HasPocoRepresentation && ReflectHelper.IsAbstractClass(persistentClass.MappedClass)) { log.Warn("entity [" + type.FullName + "] is abstract-class/interface explicitly mapped as non-abstract; be sure to supply entity-names"); } } selectBeforeUpdate = persistentClass.SelectBeforeUpdate; dynamicUpdate = persistentClass.DynamicUpdate; dynamicInsert = persistentClass.DynamicInsert; polymorphic = persistentClass.IsPolymorphic; explicitPolymorphism = persistentClass.IsExplicitPolymorphism; inherited = persistentClass.IsInherited; superclass = inherited ? persistentClass.Superclass.EntityName : null; superclassType = inherited ? persistentClass.Superclass.MappedClass : null; hasSubclasses = persistentClass.HasSubclasses; optimisticLockMode = persistentClass.OptimisticLockMode; if (optimisticLockMode > Versioning.OptimisticLock.Version && !dynamicUpdate) { throw new MappingException("optimistic-lock setting requires dynamic-update=\"true\": " + type.FullName); } hasCollections = foundCollection; hasMutableProperties = foundMutable; foreach (Subclass obj in persistentClass.SubclassIterator) { subclassEntityNames.Add(obj.EntityName); } subclassEntityNames.Add(name); tuplizerMapping = new EntityEntityModeToTuplizerMapping(persistentClass, this); }
public EntityMetamodel(PersistentClass persistentClass, ISessionFactoryImplementor sessionFactory) { this.sessionFactory = sessionFactory; name = persistentClass.EntityName; rootName = persistentClass.RootClazz.EntityName; entityType = TypeFactory.ManyToOne(name); type = persistentClass.MappedClass; rootType = persistentClass.RootClazz.MappedClass; rootTypeAssemblyQualifiedName = rootType == null ? null : rootType.AssemblyQualifiedName; identifierProperty = PropertyFactory.BuildIdentifierProperty(persistentClass, sessionFactory.GetIdentifierGenerator(rootName)); versioned = persistentClass.IsVersioned; bool lazyAvailable = persistentClass.HasPocoRepresentation && FieldInterceptionHelper.IsInstrumented(persistentClass.MappedClass); bool hasLazy = false; propertySpan = persistentClass.PropertyClosureSpan; properties = new StandardProperty[propertySpan]; List <int> naturalIdNumbers = new List <int>(); propertyNames = new string[propertySpan]; propertyTypes = new IType[propertySpan]; propertyUpdateability = new bool[propertySpan]; propertyInsertability = new bool[propertySpan]; insertInclusions = new ValueInclusion[propertySpan]; updateInclusions = new ValueInclusion[propertySpan]; nonlazyPropertyUpdateability = new bool[propertySpan]; propertyCheckability = new bool[propertySpan]; propertyNullability = new bool[propertySpan]; propertyVersionability = new bool[propertySpan]; propertyLaziness = new bool[propertySpan]; cascadeStyles = new CascadeStyle[propertySpan]; int i = 0; int tempVersionProperty = NoVersionIndex; bool foundCascade = false; bool foundCollection = false; bool foundMutable = false; bool foundInsertGeneratedValue = false; bool foundUpdateGeneratedValue = false; bool foundNonIdentifierPropertyNamedId = false; HasPocoRepresentation = persistentClass.HasPocoRepresentation; // NH: WARNING if we have to disable lazy/unproxy properties we have to do it in the whole process. lazy = persistentClass.IsLazy && (!persistentClass.HasPocoRepresentation || !ReflectHelper.IsFinalClass(persistentClass.ProxyInterface)); lazyAvailable &= lazy; // <== Disable lazy properties if the class is marked with lazy=false bool hadLazyProperties = false; bool hadNoProxyRelations = false; foreach (Mapping.Property prop in persistentClass.PropertyClosureIterator) { if (prop.IsLazy) { hadLazyProperties = true; } if (prop.UnwrapProxy) { hadNoProxyRelations = true; } // NH: A lazy property is a simple property marked with lazy=true bool islazyProperty = prop.IsLazy && lazyAvailable && (!prop.IsEntityRelation || prop.UnwrapProxy); // NH: A Relation (in this case many-to-one or one-to-one) marked as "no-proxy" var isUnwrapProxy = prop.UnwrapProxy && lazyAvailable; if (islazyProperty || isUnwrapProxy) { // NH: verify property proxiability var getter = prop.GetGetter(persistentClass.MappedClass); if (getter.Method == null || getter.Method.IsDefined(typeof(CompilerGeneratedAttribute), false) == false) { log.ErrorFormat("Lazy or no-proxy property {0}.{1} is not an auto property, which may result in uninitialized property access", persistentClass.EntityName, prop.Name); } } if (prop == persistentClass.Version) { tempVersionProperty = i; properties[i] = PropertyFactory.BuildVersionProperty(prop, islazyProperty); } else { properties[i] = PropertyFactory.BuildStandardProperty(prop, islazyProperty); } if (prop.IsNaturalIdentifier) { naturalIdNumbers.Add(i); } if ("id".Equals(prop.Name)) { foundNonIdentifierPropertyNamedId = true; } if (islazyProperty) { hasLazy = true; } if (isUnwrapProxy) { hasUnwrapProxyForProperties = true; } propertyLaziness[i] = islazyProperty; propertyNames[i] = properties[i].Name; propertyTypes[i] = properties[i].Type; propertyNullability[i] = properties[i].IsNullable; propertyUpdateability[i] = properties[i].IsUpdateable; propertyInsertability[i] = properties[i].IsInsertable; insertInclusions[i] = DetermineInsertValueGenerationType(prop, properties[i]); updateInclusions[i] = DetermineUpdateValueGenerationType(prop, properties[i]); propertyVersionability[i] = properties[i].IsVersionable; nonlazyPropertyUpdateability[i] = properties[i].IsUpdateable && !islazyProperty; propertyCheckability[i] = propertyUpdateability[i] || (propertyTypes[i].IsAssociationType && ((IAssociationType)propertyTypes[i]).IsAlwaysDirtyChecked); cascadeStyles[i] = properties[i].CascadeStyle; if (properties[i].IsLazy) { hasLazy = true; } if (properties[i].CascadeStyle != CascadeStyle.None) { foundCascade = true; } if (IndicatesCollection(properties[i].Type)) { foundCollection = true; } if (propertyTypes[i].IsMutable && propertyCheckability[i]) { foundMutable = true; } if (insertInclusions[i] != ValueInclusion.None) { foundInsertGeneratedValue = true; } if (updateInclusions[i] != ValueInclusion.None) { foundUpdateGeneratedValue = true; } MapPropertyToIndex(prop, i); i++; } if (naturalIdNumbers.Count == 0) { naturalIdPropertyNumbers = null; } else { naturalIdPropertyNumbers = naturalIdNumbers.ToArray(); } hasCascades = foundCascade; hasInsertGeneratedValues = foundInsertGeneratedValue; hasUpdateGeneratedValues = foundUpdateGeneratedValue; hasNonIdentifierPropertyNamedId = foundNonIdentifierPropertyNamedId; versionPropertyIndex = tempVersionProperty; hasLazyProperties = hasLazy; if (hadLazyProperties && !hasLazy) { log.WarnFormat("Disabled lazy property fetching for {0} because it does not support lazy at the entity level", name); } if (hasLazy) { log.Info("lazy property fetching available for: " + name); } if (hadNoProxyRelations && !hasUnwrapProxyForProperties) { log.WarnFormat("Disabled ghost property fetching for {0} because it does not support lazy at the entity level", name); } if (hasUnwrapProxyForProperties) { log.Info("no-proxy property fetching available for: " + name); } mutable = persistentClass.IsMutable; if (!persistentClass.IsAbstract.HasValue) { // legacy behavior (with no abstract attribute specified) isAbstract = persistentClass.HasPocoRepresentation && ReflectHelper.IsAbstractClass(persistentClass.MappedClass); } else { isAbstract = persistentClass.IsAbstract.Value; if (!isAbstract && persistentClass.HasPocoRepresentation && ReflectHelper.IsAbstractClass(persistentClass.MappedClass)) { log.Warn("entity [" + type.FullName + "] is abstract-class/interface explicitly mapped as non-abstract; be sure to supply entity-names"); } } selectBeforeUpdate = persistentClass.SelectBeforeUpdate; dynamicUpdate = persistentClass.DynamicUpdate; dynamicInsert = persistentClass.DynamicInsert; polymorphic = persistentClass.IsPolymorphic; explicitPolymorphism = persistentClass.IsExplicitPolymorphism; inherited = persistentClass.IsInherited; superclass = inherited ? persistentClass.Superclass.EntityName : null; superclassType = inherited ? persistentClass.Superclass.MappedClass : null; hasSubclasses = persistentClass.HasSubclasses; optimisticLockMode = persistentClass.OptimisticLockMode; if (optimisticLockMode > Versioning.OptimisticLock.Version && !dynamicUpdate) { throw new MappingException("optimistic-lock setting requires dynamic-update=\"true\": " + type.FullName); } hasCollections = foundCollection; hasMutableProperties = foundMutable; foreach (Subclass obj in persistentClass.SubclassIterator) { subclassEntityNames.Add(obj.EntityName); } subclassEntityNames.Add(name); EntityMode = persistentClass.HasPocoRepresentation ? EntityMode.Poco : EntityMode.Map; var entityTuplizerFactory = new EntityTuplizerFactory(); var tuplizerClassName = persistentClass.GetTuplizerImplClassName(EntityMode); Tuplizer = tuplizerClassName == null ? entityTuplizerFactory.BuildDefaultEntityTuplizer(EntityMode, this, persistentClass) : entityTuplizerFactory.BuildEntityTuplizer(tuplizerClassName, this, persistentClass); }
protected override bool AppliesTo(Dialect.Dialect dialect) { // this test work only with Field interception (NH-1618) return(FieldInterceptionHelper.IsInstrumented(new Person())); }