Collection is not selected with NHibernate-Caching
-
01-07-2021 - |
Question
I have the fallowing entities:
Person Company
And then, there is a entity PersonCompany which makes a Relation between Person and Company
Mapping for Person is:
public class PersonMap : SubclassMap<Person> {
public PersonMap() {
this.Table("Person");
this.KeyColumn("Id");
this.HasMany(x => x.PersonCompanys).AsSet().KeyColumn("PersonId").Fetch.Select().Inverse().Cascade.Delete();
}
}
Company:
public class CompanyMap : SubclassMap<Company> {
public CompanyMap() {
this.Table("Company");
this.KeyColumn("Id");
this.HasMany(x => x.PersonCompanys).AsSet().KeyColumn("CompanyId").Fetch.Select().Inverse().Cascade.None();
}
}
and PersonCompany:
public class PersonCompanyMap : ClassMap<PersonCompany> {
public PersonCompanyMap() {
this.Table("PersonCompany");
this.Version(x => x.ObjectVersion);
this.Id(x => x.Id).GeneratedBy.Assigned();
this.References(x => x.Company).Column("CompanyId").Fetch.Select();
this.References(x => x.Person).Column("PersonId").Fetch.Select();
}
}
SecondLevel-Caching is activated general and for each Entity with Conventions. Also the Caching for the PersonCompanys-Collection:
public class CachableConventions : IClassConvention, IHasManyConvention, IHasManyToManyConvention {
private static readonly Type[] notCachableTypes = new[] {typeof(Word), typeof(ActivityWord), typeof(DbVersion), typeof(Deleted), typeof(ExchangeSyncState), typeof(Synchronizer), typeof(SerialletterField)};
public void Apply(IClassInstance instance) {
if (Array.IndexOf(notCachableTypes, instance.EntityType) >= 0) {
return;
}
instance.Cache.ReadWrite();
}
public void Apply(IManyToManyCollectionInstance instance) {
if (Array.IndexOf(notCachableTypes, instance.ChildType) >= 0) {
return;
}
instance.Cache.ReadWrite();
}
public void Apply(IOneToManyCollectionInstance instance) {
if (Array.IndexOf(notCachableTypes, instance.ChildType) >= 0) {
return;
}
instance.Cache.ReadWrite();
}
}
Now, I create a new Person and after save a new Company and then I add a PersonCompany-Record to the PersonCompanies-Collection.
When I after select the created Person, the PersonCompanys-Collection will be empty. When I do the same without SecondLevel-Caching, the PersonCompanys-Collection contains the created Entity.
Does someone know, what can going wrong here?
Edit - Additional Informations:
This steps are causing the problem:
- create a new Person with
Session.Save(person)
- load the person with
person = Session.Get(person.Id)
- get personCompany from the Person with
personCompany = person.PersonCompany.FirstOrDefault()
(this will be empty) - Create a new PersonCompany-Entry with
Session.Save(new PersonCompany(Guid.NewGuid()) {Person = person}))
- load the person with
person = Session.Get(person.Id)
- now,
person.PersonCompany
returns an empty list.
When I do not step 3, all is working great.
Solution
- see obove
- see obove
get personCompany from the Person with personCompany = person.PersonCompany.FirstOrDefault() (this will be empty)
this will initialise the collection to an empty collection
Create a new PersonCompany-Entry with Session.Save(new PersonCompany(Guid.NewGuid()) {Person = person}))
will create a PersonCompany record in the database
load the person with person = Session.Get(person.Id)
will just return the cached person object, so this is basicly "do nothing"
now, person.PersonCompany returns an empty list
since the collection was initialised to en empty collection in step 3 it will return just that. nhibernate will not issue another select to find out if something changed. if it would it would probably discard local changes or produce conflicts and it would not be very efficient
do
session.Clear();
as step 3b orsession.Refresh(person);
as step 5
then it is working as expected