Refresh cache functionality

Topics: User Forum
Mar 24, 2008 at 4:10 PM
Hello Lifeng,

is there any feature planned that allows managing the cache directly with operations such as remove, refresh, clear etc.?
By now one has to decide very carefully, which object to mark with the CacheableAttribute because otherwise you get the old versions of nested child objects that have already been updated by calling Object.Save() method.

Any answer would be appreciated.


neolys
Coordinator
Mar 25, 2008 at 2:33 AM
Edited Mar 25, 2008 at 2:33 AM
There is no such plan but I will do it if it is necessary.

And I'm not sure of your problem. Please give me a sample code to show it.
Mar 26, 2008 at 8:13 PM
Edited Mar 26, 2008 at 8:31 PM
Hi Lifeng,

here´s my testing code (all used classes are marked cacheable and inherit from LinqObjectModel<T>):

Test Case Failures:
1) Docas.UnitTests.Common.ModelTest.T0300HRMJobRoleRelation : System.NullReferenceException : Der Objektverweis wurde nicht auf eine Objektinstanz festgelegt.
bei Docas.UnitTests.Common.ModelTest.T0300HRMJobRoleRelation() in d:\dev\projects\cs\products\Docas\Docas.UnitTests\ModelTests.cs:Zeile 795.

This exception is only thrown on the last line of the testing method when caching is enabled.


Test
public void T0300HRMJobRoleRelation()
{
// get system user
var u = User.FindOne(x => x.Name == "SYSTEM");
Assert.IsNotNull(u);

// get organisational unit
var ou = OrganisationalUnit.FindOne(x => x.Id == 1);
Assert.IsNotNull(ou);

// get employee
var emp = Employee.FindOne(x => x.Id == 1);
Assert.IsNotNull(emp);

// create employee job role relation
EmployeeRoleRelation rel1 = EmployeeRoleRelation.New();
rel1.CreatedBy = u.Id;
rel1.Active = true;
rel1.Start = DateTime.Now;
rel1.Employee = emp;
rel1.Save();


// create job role relation
JobRoleRelation rel = JobRoleRelation.New();
rel.CreatedBy = u.Id;
rel.Active = true;
rel.Type = JobRoleRelationType.Manager;
rel.OrganisationalUnit = ou;
rel.Save();

JobRole jr = JobRole.New();
jr.CreatedBy = u.Id;
jr.Code = "CEO";
jr.Name = "CEO";
jr.Description = "CEO";
jr.JobRoleRelations.Add(rel);
jr.EmployeeRoleRelations.Add(rel1);
jr.Save();


// get organisational unit
ou = OrganisationalUnit.FindOne(x => x.Id == 1);
Assert.IsNotNull(ou);

Assert.AreEqual(1, ou.JobRoleRelations.Count);
Assert.AreEqual("CEO", ou.JobRoleRelations0.JobRole.Code);
Assert.AreEqual(1, ou.JobRoleRelations0.JobRole.EmployeeRoleRelations.Count);
Assert.AreEqual("Mustermann", ou.JobRoleRelations0.JobRole.EmployeeRoleRelations0.Employee.Person.LastName);
}

SQL-Recorder output
.T0300HRMJobRoleRelation --> BEGIN
Select Id,DC,UC,DM,UM,AF,LF,USER_NAME,USER_PASS,PERSON_ID,PROFILE_ID From DCS_USERS Where USER_NAME = @USERNAME0;
<Text><60>(@USERNAME0=SYSTEM:String)

Select Id,DC,UC,DM,UM,UNIT_NAME,UNIT_CODE,COST_CENTRE,CN,UNIT_PARENT From REF_ORG_UNIT Where Id = @Id_0;
<Text><60>(@Id_0=1:Int64)

Select Id,DC,UC,DM,UM From HRM_EMPLOYEES Where Id = @Id_0;
<Text><60>(@Id_0=1:Int64)

CREATE TABLE REL_EMP_JOB_ROLE (
Id bigint IDENTITY NOT FOR REPLICATION NOT NULL PRIMARY KEY,
DC datetime NOT NULL ,
UC bigint NOT NULL ,
DM datetime NULL ,
UM bigint NULL ,
AF bit NOT NULL ,
START_DATE datetime NULL ,
END_DATE datetime NULL ,
EMPLOYEE_ID bigint NOT NULL ,
JOB_ROLE_ID bigint NULL
);
CREATE INDEX IX_REL_EMP_JOB_ROLE_FK1 ON REL_EMP_JOB_ROLE (EMPLOYEE_ID ASC);
CREATE INDEX IX_REL_EMP_JOB_ROLE_FK2 ON REL_EMP_JOB_ROLE (JOB_ROLE_ID ASC);
<Text><30>()

Insert Into REL_EMP_JOB_ROLE (DC,UC,UM,AF,START_DATE,END_DATE,EMPLOYEE_ID,JOB_ROLE_ID) Values (getdate(),@UC0,@UM1,@AF2,@STARTDATE3,@ENDDATE4,@EMPLOYEEID5,@JOBROLEID6);
select SCOPE_IDENTITY();
<Text><30>(@UC0=1:Int64,@UM1=0:Int64,@AF2=True:Boolean,@STARTDATE3=26.03.2008 19:53:19:DateTime,@ENDDATE4=<NULL>:DateTime,@EMPLOYEEID5=1:Int64,@JOBROLEID6=0:Int64)

CREATE TABLE REL_JOB_ROLE_ORG_UNIT (
Id bigint IDENTITY NOT FOR REPLICATION NOT NULL PRIMARY KEY,
DC datetime NOT NULL ,
UC bigint NOT NULL ,
DM datetime NULL ,
UM bigint NULL ,
AF bit NOT NULL ,
RELATION_TYPE int NOT NULL ,
ORG_UNIT_ID bigint NOT NULL ,
JOB_ROLE_ID bigint NOT NULL
);
CREATE INDEX IX_REL_JOB_ROLE_ORG_UNIT_FK1 ON REL_JOB_ROLE_ORG_UNIT (ORG_UNIT_ID ASC);
CREATE INDEX IX_REL_JOB_ROLE_ORG_UNIT_FK2 ON REL_JOB_ROLE_ORG_UNIT (JOB_ROLE_ID ASC);
<Text><30>()

Insert Into REL_JOB_ROLE_ORG_UNIT (DC,UC,UM,AF,RELATION_TYPE,ORG_UNIT_ID,JOB_ROLE_ID) Values (getdate(),@UC0,@UM1,@AF2,@RELATIONTYPE3,@ORGUNITID4,@JOBROLEID_5);
select SCOPE_IDENTITY();
<Text><30>(@UC0=1:Int64,@UM1=0:Int64,@AF2=True:Boolean,@RELATIONTYPE3=Manager:Int32,@ORGUNITID4=1:Int64,@JOBROLEID_5=0:Int64)

CREATE TABLE HRM_JOB_ROLES (
Id bigint IDENTITY NOT FOR REPLICATION NOT NULL PRIMARY KEY,
DC datetime NOT NULL ,
UC bigint NOT NULL ,
DM datetime NULL ,
UM bigint NULL ,
ROLE_NAME nvarchar (64) NOT NULL ,
CODE nvarchar (36) NOT NULL ,
DESCRIPTION nvarchar (256) NOT NULL ,
ROLE_PARENT bigint NULL
);
CREATE INDEX IX_HRM_JOB_ROLES_1 ON HRM_JOB_ROLES (ROLE_NAME ASC);
CREATE UNIQUE INDEX IX_HRM_JOB_ROLES_UK1 ON HRM_JOB_ROLES (CODE ASC);
CREATE INDEX IX_HRM_JOB_ROLES_FK1 ON HRM_JOB_ROLES (ROLE_PARENT ASC);
<Text><30>()

Insert Into HRM_JOB_ROLES (DC,UC,UM,ROLE_NAME,CODE,DESCRIPTION,ROLE_PARENT) Values (getdate(),@UC0,@UM1,@ROLENAME2,@CODE3,@DESCRIPTION4,@ROLEPARENT5);
select SCOPE_IDENTITY();
<Text><30>(@UC0=1:Int64,@UM1=0:Int64,@ROLENAME2=CEO:String,@CODE3=CEO:String,@DESCRIPTION4=CEO:String,@ROLEPARENT5=0:Int64)

Update REL_JOB_ROLE_ORG_UNIT Set UC=@UC0,DM=getdate(),AF=@AF1,RELATION_TYPE=@RELATIONTYPE2,ORG_UNIT_ID=@ORGUNITID3,JOB_ROLE_ID=@JOBROLEID4 Where Id = @Id_5;
<Text><30>(@UC0=1:Int64,@AF1=True:Boolean,@RELATIONTYPE2=Manager:Int32,@ORGUNITID3=1:Int64,@JOBROLEID4=1:Int64,@Id_5=1:Int64)

Update REL_EMP_JOB_ROLE Set UC=@UC0,DM=getdate(),AF=@AF1,START_DATE=@STARTDATE2,EMPLOYEE_ID=@EMPLOYEEID3,JOB_ROLE_ID=@JOBROLEID4 Where Id = @Id5;
<Text><30>(@UC0=1:Int64,@AF1=True:Boolean,@STARTDATE2=26.03.2008 19:53:19:DateTime,@EMPLOYEEID3=1:Int64,@JOBROLEID4=1:Int64,@Id5=1:Int64)

Select Id,DC,UC,DM,UM,UNIT_NAME,UNIT_CODE,COST_CENTRE,CN,UNIT_PARENT From REF_ORG_UNIT Where Id = @Id_0;
<Text><60>(@Id_0=1:Int64)

Select Id,DC,UC,DM,UM,AF,RELATION_TYPE,ORG_UNIT_ID,JOB_ROLE_ID From REL_JOB_ROLE_ORG_UNIT Where ORG_UNIT_ID = @ORGUNITID_0;
<Text><60>(@ORGUNITID_0=1:Int64)

Select Id,DC,UC,DM,UM,ROLE_NAME,CODE,DESCRIPTION,ROLE_PARENT From HRM_JOB_ROLES Where Id = @Id_0;
<Text><60>(@Id_0=1:Int64)

Select Id,DC,UC,DM,UM,AF,START_DATE,END_DATE,EMPLOYEE_ID,JOB_ROLE_ID From REL_EMP_JOB_ROLE Where JOB_ROLE_ID = @JOBROLEID_0;
<Text><60>(@JOBROLEID_0=1:Int64)

When caching is disabled the following additional SQL-statements are issued:

Select Id,DC,UC,DM,UM From HRM_EMPLOYEES Where Id = @Id_0;
<Text><60>(@Id_0=1:Int64)

select Id,DC,UC,DM,UM,NAME_FIRST,NAME_LAST,NAME_MIDDLE,NAME_PREFIX,NAME_POSTFIX,GENDER,DOB,DOD,EMPLOYEE_ID from (select Id,DC,UC,DM,UM,NAME_FIRST,NAME_LAST,NAME_MIDDLE,NAME_PREFIX,NAME_POSTFIX,GENDER,DOB,DOD,EMPLOYEE_ID, ROWNUMBER() OVER ( Order By Id ASC) as _rownumber_ From DCS_PERSONS Where EMPLOYEE_ID = @EMPLOYEEID0) as T Where T._rownumber__ >= 1 and T._rownumber_ <= 1;
<Text><60>(@EMPLOYEEID0=1:Int64)

Thanks in advance

neolys
Coordinator
Mar 27, 2008 at 3:08 AM
This discussion has been copied to a work item. Click here to go to the work item and continue the discussion.
Coordinator
Mar 28, 2008 at 2:51 AM
If you want manage the cache directly. Please use the following code:
Lephone.Data.Caching.CacheProvider.Instance.Remove(Key);
Lephone.Data.Caching.CacheProvider.Instance.Clear();
Lephone.Data.Caching.CacheProvider.Instance[key] = value;
Mar 28, 2008 at 9:04 PM
Thanks for your help, removing deeply nested objects from cache helps for now.
I will try finding out why deeply nested cached objects are not instantiated correctly (eg. ou.JobRoleRelations[0].JobRole.EmployeeRoleRelations[0].Employee.Person.LastName).
Coordinator
May 21, 2008 at 1:11 PM
Done.