I have seen this warning in my NHibernate-DataAccess:
'Disabled ghost property fetching for entity because it does not support lazy at the entity level'
Does someone know, what does this mean? - What does I have to change to solve this?
Here is a mapping for an entity, which is causing this warning:
public class BusinessTypeMap : ClassMap<BusinessType> {
public BusinessTypeMap() {
this.Table("BusinessType");
this.Version(x => x.ObjectVersion);
this.Id(x => x.Id).GeneratedBy.Assigned();
this.Map(x => x.Key).Length(8).Nullable();
this.Map(x => x.Name).Length(50).Not.Nullable();
this.Map(x => x.Comment).Length(8000).Nullable();
this.Map(x => x.Created).Not.Nullable().Not.OptimisticLock();
this.Map(x => x.CreatedBy).Length(255).Not.Nullable().Not.OptimisticLock();
this.Map(x => x.Changed).Nullable().Not.OptimisticLock();
this.Map(x => x.ChangedBy).Length(255).Nullable().Not.OptimisticLock();
this.HasMany(x => x.LocalizedProperties).AsSet().KeyColumn("EntityId").Where("LocalizedEntityClass = 'Prayon.Entities.BusinessType'").ForeignKeyConstraintName("none").Cascade.All();
this.HasMany(x => x.Companys).AsSet().KeyColumn("BusinessTypeId").Fetch.Select().Inverse().Cascade.None();
this.References(x => x.Client).Column("ClientId").Fetch.Select();
}
}
Update definition of class BusinessTypeBase:
[Serializable]
public abstract class BusinessTypeBase : AuditableEntityBase, ILocalizedEntity {
#region Private Variables
protected String key;
protected String name;
protected String comment;
#endregion
#region Constructors
protected BusinessTypeBase() {
this.LocalizedProperties = new HashSet<LocalizedProperty>();
OnCreated();
}
protected BusinessTypeBase(Guid id, String key, String name, String comment) {
this.LocalizedProperties = new HashSet<LocalizedProperty>();
this.id = id;
this.key = key;
this.name = name;
this.comment = comment;
OnCreated();
}
protected BusinessTypeBase(Guid id, String name) {
this.LocalizedProperties = new HashSet<LocalizedProperty>();
this.id = id;
this.name = name;
OnCreated();
}
#endregion
#region Puplic Properties
public virtual String Key {
get { return key; }
set {
if (this.key != value) {
this.OnKeyChanging(value);
this.key = value;
this.OnKeyChanged();
}
}
}
/// <summary>
/// @loc
/// </summary>
[Localize("Name")]
public virtual String Name {
get { return name; }
set {
if (this.name != value) {
this.OnNameChanging(value);
this.name = value;
this.OnNameChanged();
}
}
}
public virtual String NameLocalized {
get { return this.GetLocalized(x => x.Name); }
set {
if (this.NameLocalized != value) {
this.OnNameLocalizedChanging(value);
this.AddLocalizedProperty(x => x.Name, value);
this.OnNameLocalizedChanged();
if (string.IsNullOrEmpty(this.Name)) {
this.Name = value;
}
}
}
}
protected virtual void OnNameLocalizedChanging(String value) {
}
protected virtual void OnNameLocalizedChanged() {
}
[IgnoreForDeleteSerialization]
public virtual String Comment {
get { return comment; }
set {
if (this.comment != value) {
this.OnCommentChanging(value);
this.comment = value;
this.OnCommentChanged();
}
}
}
#endregion
#region Version
protected Int32 objectVersion;
public virtual Int32 ObjectVersion {
get { return objectVersion; }
set {
if (this.objectVersion != value) {
this.objectVersion = value;
}
}
}
#endregion
#region CollectionRules
public override string[] CollectionRules {
get { return collectionRules; }
}
private static readonly string[] collectionRules = new string[]
{
"Prayon.Entities.Client.BusinessTypes"
};
#endregion
#region Company Association
protected virtual void OnCompanysChanging(ICollection<Company> value) {
}
protected virtual void OnCompanysChanged() {
}
private ICollection<Company> companys = new HashSet<Company>();
[IgnoreForDeleteSerialization]
public virtual ICollection<Company> Companys {
get { return companys; }
set {
if (this.companys != value) {
this.OnCompanysChanging(value);
this.companys = value;
this.OnCompanysChanged();
}
}
}
#endregion
#region Client Association
public virtual Guid SerializableClient {
get { return (this.Client == null ? (this.SerializationProxies.ContainsKey("ClientId") ? this.SerializationProxies["ClientId"] : Guid.Empty) : this.Client.Id); }
set { this.SerializationProxies["ClientId"] = value; }
}
protected virtual void OnClientChanging(Client value) {
}
protected virtual void OnClientChanged() {
}
private Client client;
[IgnoreForDeleteSerialization]
public virtual Client Client {
get { return client; }
set {
if (this.client != value) {
this.OnClientChanging(value);
this.client = value;
this.OnClientChanged();
}
}
}
#endregion
#region ICloneable Members
///<summary>
/// Returns a Typed Copy of BusinessType
///</summary>
public virtual object Clone() {
BusinessType copy = new BusinessType();
copy.id = this.id;
copy.key = this.key;
copy.name = this.name;
copy.comment = this.comment;
return copy;
}
#endregion
#region Check Equality
/// <summary>
/// Check if the Passed Parameter is value equaled to this Address.
/// </summary>
/// <param name="obj">The Object will ba compared to.</param>
/// <returns>True if Equal else False</returns>
public override bool Equals(object obj) {
if (obj is BusinessTypeBase) {
var entity = obj as BusinessTypeBase;
if (entity.id != this.id)
return false;
if (entity.key != this.key)
return false;
if (entity.name != this.name)
return false;
if (entity.comment != this.comment)
return false;
return true;
}
return base.Equals(obj);
}
public override int GetHashCode() {
int hash = 0;
hash = hash ^ this.id.GetHashCode();
if (this.key != null) {
hash = hash ^ this.key.GetHashCode();
}
if (this.name != null) {
hash = hash ^ this.name.GetHashCode();
}
if (this.comment != null) {
hash = hash ^ this.comment.GetHashCode();
}
return hash;
}
public static bool operator ==(BusinessTypeBase obj1, BusinessTypeBase obj2) {
if (object.ReferenceEquals(obj1, null) && object.ReferenceEquals(obj2, null)) {
return true;
}
if (object.ReferenceEquals(obj1, null) || object.ReferenceEquals(obj2, null)) {
return false;
}
return obj1.Equals(obj2);
}
public static bool operator !=(BusinessTypeBase obj1, BusinessTypeBase obj2) {
return !(obj1 == obj2);
}
#endregion
#region To String
/// <summary>
/// override ToString to produce XML format of the current object
/// </summary>
public override string ToString() {
StringBuilder stringBuilder = new StringBuilder();
stringBuilder.AppendFormat("<Id>{0}</Id>{1}", this.id.ToString(), System.Environment.NewLine);
if (this.key != null)
stringBuilder.AppendFormat("<Key>{0}</Key>{1}", this.key.ToString(), System.Environment.NewLine);
if (this.name != null)
stringBuilder.AppendFormat("<Name>{0}</Name>{1}", this.name.ToString(), System.Environment.NewLine);
if (this.comment != null)
stringBuilder.AppendFormat("<Comment>{0}</Comment>{1}", this.comment.ToString(), System.Environment.NewLine);
return stringBuilder.ToString();
}
#endregion
#region Extensibility Method Definitions
protected virtual void OnCreated() {
}
protected virtual void OnKeyChanging(String value) {
}
protected virtual void OnKeyChanged() {
}
protected virtual void OnNameChanging(String value) {
}
protected virtual void OnNameChanged() {
}
protected virtual void OnCommentChanging(String value) {
}
protected virtual void OnCommentChanged() {
}
#endregion
#region Localization
public virtual ICollection<LocalizedProperty> LocalizedProperties { get; set; }
#endregion
}
Update definition of class BusinessType:
[Serializable]
public partial class BusinessType : BusinessTypeBase {
#region Constructors
public BusinessType()
: base() {
}
public BusinessType(Guid id, String key, String name, String comment)
: base(id, key, name, comment) {
}
public BusinessType(Guid id, String name)
: base(id, name) {
}
#endregion
}
Have you tried using*)Iesi.Collections.Generic.ISet<Company>
instead ofICollection<Company>
? IIRC, NHibernate used different interface set than EF or other typical libraries. The general problem is that ICollection is quite bad contract here, as it does not state the "SET" behaviour, which in fact every relation is.edit: *) I just found out that I were wrong, NH can cooperate with ICollection interface (https://stackoverflow.com/a/4673125/717732). Still you can try with ISet or HashSet, but I now doubt that that's the problem, sorry :/