override Save

Posts   
 
    
mdissel
User
Posts: 92
Joined: 16-Sep-2003
# Posted on: 08-Jul-2004 16:06:03   

Hello

For my logging framework i need to store the username / userid (or whatever) so that nothing can be saved without knowing who did it. (again using self servicing)

My current idea is to create a method Save(string Username) and override the default Save and throw an exception if that method is choosen. But EntityBase.Save() is not implemented as virtual...

Now i realize that this wouldn't store history records when recursive save is used (that will not use the override Save class)...I think i need a different approach... Maybe at a static variable to the DbUtils class where i store my UserID/Name and use that value in the InsertEntity/UpdateEntity

Feedback is welcome!

Thanks

Marco

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39614
Joined: 17-Aug-2003
# Posted on: 08-Jul-2004 18:53:35   

check this posting: http://www.llblgen.com/tinyforum/Messages.aspx?ThreadID=992&StartAtMessage=0&#5572

(the # is not added to the URL, use that to jump to my message at the bottom). It illustrates (option 1) how to inject code into the derived classes to override UpdateEntity(). You can also use that to override InsertEntity() and grab the username from some class, for example a static as you suggested. You can use the same technique to inject code for this static member in dbUtils for example.

Frans Bouma | Lead developer LLBLGen Pro
mdissel
User
Posts: 92
Joined: 16-Sep-2003
# Posted on: 14-Jul-2004 09:20:21   

I've modified the InsertEntity/UpdateEntity and Delete() methods in the EntityBase classes to create a record that will hold the previous values of the fields. This record should only be created when the Save action of the entity will succeed..

I need transaction support. What's the best place to insert code to create a "history record" that will be part of the current transaction (or start a new one).

Thanks

Marco

ps using selfservices, latest version

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39614
Joined: 17-Aug-2003
# Posted on: 14-Jul-2004 10:02:56   

Simply grab the base.Transaction instance and add your entity to that transaction by calling Add simple_smile

thus:

base.Transaction.Add(myNewEntity);

// continue

Frans Bouma | Lead developer LLBLGen Pro
mdissel
User
Posts: 92
Joined: 16-Sep-2003
# Posted on: 14-Jul-2004 13:06:20   

But where should i place this code?

This is my code to create and store the historyrecord (inside the BaseEntityClass)


protected override bool UpdateEntity(IPredicate updateRestriction)
{
RecordHistoryUtils.StoreRecordHistory(Expo.DAL.HelperClasses.RecordAction.Modify, this );   
BedrijfContactpersoonDAO dao = DAOFactory.CreateBedrijfContactpersoonDAO();
return dao.UpdateBedrijfContactpersoon(base.Fields, base.Transaction, updateRestriction);
}

.StoreRecordHistory will create a new RecordHistoryEntity object that will hold the old values. the newly RecordHistoryEntity is also saved in this function.

Where should i place base.Transaction.Add(newRecordHistoryEntity)? and where should i commit the (new or existing) transaction without modifying anything else.

Thanks

Marco

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39614
Joined: 17-Aug-2003
# Posted on: 14-Jul-2004 13:53:42   

mdissel wrote:

But where should i place this code?

This is my code to create and store the historyrecord (inside the BaseEntityClass)


protected override bool UpdateEntity(IPredicate updateRestriction)
{
RecordHistoryUtils.StoreRecordHistory(Expo.DAL.HelperClasses.RecordAction.Modify, this );   
BedrijfContactpersoonDAO dao = DAOFactory.CreateBedrijfContactpersoonDAO();
return dao.UpdateBedrijfContactpersoon(base.Fields, base.Transaction, updateRestriction);
}

.StoreRecordHistory will create a new RecordHistoryEntity object that will hold the old values. the newly RecordHistoryEntity is also saved in this function.

Where should i place base.Transaction.Add(newRecordHistoryEntity)? and where should i commit the (new or existing) transaction without modifying anything else.

As you pass the entity to StoreRecordHistory, you have to add teh entity there to the transaction, so you can in there do: (assumes there is always a transaction).

// inside StoreRecordHistory, savedEntity is the entity passed to it savedEntity.Transaction.Add(newRecordHistory); // proceed as you currently do.

note: there is one caveat: when you call an entity's save method like this: Save(), there is no transaction. It is not wise to start one that late in the save process either. If you want both to be ran in the same transaction, either start one before calling save, or pass 'true' for recurse to the Save() method. This will do a recursive save but will start a transaction before doing anything else, making sure that there is a transaction available.

With an include template you can 'hide' Save() from the base classes with a new implementation which always calls Save(null, true), making sure no-one makes a mistake.

Frans Bouma | Lead developer LLBLGen Pro
mdissel
User
Posts: 92
Joined: 16-Sep-2003
# Posted on: 14-Jul-2004 14:14:59   

Otis wrote:

note: there is one caveat: when you call an entity's save method like this: Save(), there is no transaction. It is not wise to start one that late in the save process either. If you want both to be ran in the same transaction, either start one before calling save, or pass 'true' for recurse to the Save() method. This will do a recursive save but will start a transaction before doing anything else, making sure that there is a transaction available.

With an include template you can 'hide' Save() from the base classes with a new implementation which always calls Save(null, true), making sure no-one makes a mistake.

Thanks! That's the part where i struggeled with the code implementation..

Marco