Entity is out sync when called from the Auditor

Posts   
 
    
cfmacorol
User
Posts: 2
Joined: 27-Sep-2021
# Posted on: 27-Sep-2021 19:07:52   

[using Version5.8] Hello there! In a custom auditor class, we are fetching by database id the entity EmpGeneralEntity, which is being newly created in the database call that is being audited. The purpose of the entity fetch is to prefetch data fields in a related entity (through a foreign key relationship with an entity called DomainEntity - EmpGeneralEntity has DomainId which is the foreign key database id of the DomainEntity) that are ultimately logged into the AuditLog. However, when accessing the fields of the prefetched related entity, there’s an OutOfSync error. Then if the state of that entity is manually set to Fetched, the data fields show as null or 0.

Is there a way to access these fields in the Auditor?

Walaa avatar
Walaa
Support Team
Posts: 14946
Joined: 21-Aug-2005
# Posted on: 27-Sep-2021 21:03:06   

No. That's not the best place for this logic. The auditor is called right after saving the EmpGeneralEntity, which is being inserted/created in your case. Related entities referencing this entity would not be persisted yet, at this time.

(Edit) I believe I didn't understand the case correctly

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39590
Joined: 17-Aug-2003
# Posted on: 28-Sep-2021 09:13:49   

If the domainentity exists in the DB, then it should contain data tho. It's a bit unclear on which entity the outofsync occurs at: the fetched domainentity?

Could you please provide more info: what database, selfservicing or adapter and please provide a code snippet what exactly you're doing.

Frans Bouma | Lead developer LLBLGen Pro
cfmacorol
User
Posts: 2
Joined: 27-Sep-2021
# Posted on: 28-Sep-2021 16:22:29   

Otis wrote:

If the domainentity exists in the DB, then it should contain data tho. It's a bit unclear on which entity the outofsync occurs at: the fetched domainentity?

Could you please provide more info: what database, selfservicing or adapter and please provide a code snippet what exactly you're doing.

The fetched EmpGeneralEntity is the one that's out of sync. We're using an Oracle database and adapter.

// Here's how we call the fetch function and try to access the data fields
Grb.Platform.Framework.Business.Lower.FactoryAdapter.AdapterConnection adapterConnection = Grb.Platform.Framework.Business.Lower.AuditUtility.CreateAdapterConnection();
Grb.Platform.Framework.Business.Lower.EntityClasses.EmpGeneralEntity empGeneralEntity = GetEmpGeneralEntityByEmployeeId(employeeId, adapterConnection);
auditInformation.DomainId = empGeneralEntity.DomainId.ToString(System.Globalization.CultureInfo.InvariantCulture);
auditInformation.DomainNumber = empGeneralEntity.Domain.Domainnumber.ToString(System.Globalization.CultureInfo.InvariantCulture);


// Here's where we try to fetch the EmpGeneralEntity from the Auditor 
private static Grb.Platform.Framework.Business.Lower.EntityClasses.EmpGeneralEntity GetEmpGeneralEntityByEmployeeId(int employeeId, Grb.Platform.Framework.Business.Lower.FactoryAdapter.AdapterConnection adapterConnection)
{
    Grb.Platform.Framework.Business.Lower.EntityClasses.EmpGeneralEntity empGeneralEntity = new Grb.Platform.Framework.Business.Lower.EntityClasses.EmpGeneralEntity(employeeId);

    SD.LLBLGen.Pro.ORMSupportClasses.IncludeFieldsList empGeneralIncludeFieldsList = new SD.LLBLGen.Pro.ORMSupportClasses.IncludeFieldsList();
    empGeneralIncludeFieldsList.Add(Grb.Platform.Framework.Business.Lower.HelperClasses.EmpGeneralFields.DomainId);

    var preFetchPath = new SD.LLBLGen.Pro.ORMSupportClasses.PrefetchPath2(Grb.Platform.Framework.Business.Lower.EntityType.EmpGeneralEntity);

    var domainIncludeFieldsList = new SD.LLBLGen.Pro.ORMSupportClasses.IncludeFieldsList();
    domainIncludeFieldsList.Add(Grb.Platform.Framework.Business.Lower.HelperClasses.DomainFields.Domainnumber);

    preFetchPath.Add(Grb.Platform.Framework.Business.Lower.EntityClasses.EmpGeneralEntity.PrefetchPathDomain, domainIncludeFieldsList);

    using (SD.LLBLGen.Pro.ORMSupportClasses.IDataAccessAdapter adapter = Grb.Platform.Framework.Business.Lower.FactoryAdapter.FactoryAdapter.GetDataAccessAdapter(adapterConnection))
    {
      adapter.FetchEntity(empGeneralEntity, preFetchPath, null, empGeneralIncludeFieldsList);
    }

    return empGeneralEntity;
}
Walaa avatar
Walaa
Support Team
Posts: 14946
Joined: 21-Aug-2005
# Posted on: 29-Sep-2021 04:02:17   

At which line is the exception thrown? Is it the second line of code?

Are you sure there is an entity returned by the fetch call?

Please examine the return value of the FetchEntity method.

Also please capture the SQL query produced for the fetch method and execute it manually against the database, to see if it indeed return a valid record.

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39590
Joined: 17-Aug-2003
# Posted on: 29-Sep-2021 10:17:37   

yeah I think the fetch entity method fails. In Oracle you have MVCC so reading from the table again (which this does) might read the original value (as readers don't block writers), and as the empgeneral entity was just saved (but the transaction isn't finalized!) it's not there. You create a new adapter, so the one used for the save of empgeneral holds the transaction, the new one creates a new connection and unless you have specified readuncommitted as isolation level, the new connection won't see the persisted entities (but not committed yet!) as the transaction hasn't been completed in the other adapter.

Can't you just fetch the domain entity with a predicate with teh domainid ? You don't need the prefetch path as the empgeneral entity is already in the auditor, and you need the domainentity for auditing info only.

Frans Bouma | Lead developer LLBLGen Pro