Refetch possible bug

Posts   
 
    
jspanocsi
User
Posts: 145
Joined: 04-Mar-2005
# Posted on: 16-Jul-2007 15:45:04   

I might have found a bug in refetch, but I may not be using it right either.

runtime version i'm using now is 2.0.7.611

Say I have an orderentity with an added field (customer name) from the customers table using the fields on related fields tab in the designer.

now I have a preexisting order with a customer name of john. The user goes to an edit form and changes the customer link from john to joe using a customer drop down. The id of the orderentity field for the customer gets changed to the joe record id in the customers table. at this point in time, everything is fine. the added field of customername says joe etc. now the user decides not to save it but hits the undo button on my form. I do an orderentity.refetch in code when they do this. The main order entity reverts back to what it was fine, but the added fields don't get updated. the orderentity.customername still says joe instead of going back to john.

am I doing something wrong here or is that a bug?

Thanks!

Aurelien avatar
Aurelien
Support Team
Posts: 162
Joined: 28-Jun-2006
# Posted on: 16-Jul-2007 16:17:17   

Hi,

Can you post the piece of code witch is not working ?

jspanocsi
User
Posts: 145
Joined: 04-Mar-2005
# Posted on: 16-Jul-2007 16:19:27   

it will be very hard to do that as it's hundreds of thousands of lines in a huge app. i could probably get an example of it though.

it should be easy to duplicate. take an entity with a key to another table and a related field. change the key and then do a entity.refetch and the related field should be wrong.

i'll see if I can work up an example

Aurelien avatar
Aurelien
Support Team
Posts: 162
Joined: 28-Jun-2006
# Posted on: 16-Jul-2007 16:24:35   

Hi,

Maybe you can start with the code executed whe you click on the "undo" button ?

jspanocsi
User
Posts: 145
Joined: 04-Mar-2005
# Posted on: 16-Jul-2007 16:27:48   

ok here it is

Dim ent As EntityBase = GetCurrentEntity()

        ent.CancelEdit()
        ent.DiscardSavedFields()

        ent.Refetch()

ent is the current entity they are working on, say the orders entity etc.

thanks.

Walaa avatar
Walaa
Support Team
Posts: 14950
Joined: 21-Aug-2005
# Posted on: 17-Jul-2007 10:25:20   

To reload an entity and its related entities, you should re-do the initial loading. Use the PK to fetch a new entity a PrefetchPath to fetch the related entities.

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39616
Joined: 17-Aug-2003
# Posted on: 17-Jul-2007 11:22:40   

To elaborate a bit more on what Walaa said: there's no graph versioning, just entity field versioning. This means that if you want to roll back a graph state (which you are doing, as the graph order - > Customer changed and you want to roll it back to the initial state) you have to re-do the fetch OR revert to a serialized version of the complete graph. I'd go for refetching the complete graph.

We didn't implement graph versioning as it becomes very very complex after a few hops in the graph and comes down to serializing the complete graph into a blob, let the user make changes, and if you want to revert back to the original graph, you also want to revert to original references, and while deserializing the graph data of a previous state is possible, resetting all the references is a pain, if not impossible (as it's unknown from the referenced object which objects reference it)

Frans Bouma | Lead developer LLBLGen Pro
jspanocsi
User
Posts: 145
Joined: 04-Mar-2005
# Posted on: 17-Jul-2007 14:33:13   

thanks guys. what's the easiest way to accomplish this considering I don't know what the entity really is? This is on a base form that handles hundreds of front end forms for all my enter edit screens. ent is defined as a plain entity. I don't know what the primary key is etc. Is there an easy way to just say, hey get this whole entity from the db like it's a brand new fetch?

Thanks.

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39616
Joined: 17-Aug-2003
# Posted on: 18-Jul-2007 10:37:06   

Where does 'ent' come from? Could you set a delegate or use a virtual method in the base form (which is then overriden in the derived form) to fetch the entity (indirectly if needed, e.g. the form then calls again the BL method which fetches the entity)

Frans Bouma | Lead developer LLBLGen Pro
jspanocsi
User
Posts: 145
Joined: 04-Mar-2005
# Posted on: 18-Jul-2007 13:58:35   

i could but that would be bad simple_smile i'd have to implement that on hundreds of forms...

ent is the current entity they are working with. it's found by what row is selected in a grid and we just cast it to an entitybase. it could be a customer, order, po etc etc. over 300 tables and hence 300 forms I'd have to do that on. Why doesn't the refetch method just actually refetch the entity? just like you had just pulled it from the db? I think there should be some method I can call to do this. IE make the whole graph new again Thanks.

Walaa avatar
Walaa
Support Team
Posts: 14950
Joined: 21-Aug-2005
# Posted on: 18-Jul-2007 15:22:24   

Why doesn't the refetch method just actually refetch the entity? just like you had just pulled it from the db? I think there should be some method I can call to do this. IE make the whole graph new again

I think the fetch method needs to know the entity type and whether to fetch its related entities or not, and which related entities to fetch.

Since you want to use an EntityBase instance, not casted to any type. The fetch logic won't be able to know its type (to which type it should be casted in order to fetch it again). i.e. its related entities types.

IMHO, Generailization can't work in this situation.

jspanocsi
User
Posts: 145
Joined: 04-Mar-2005
# Posted on: 18-Jul-2007 15:27:35   

Walaa wrote:

Why doesn't the refetch method just actually refetch the entity? just like you had just pulled it from the db? I think there should be some method I can call to do this. IE make the whole graph new again

I think the fetch method needs to know the entity type and whether to fetch its related entities or not, and which related entities to fetch.

Since you want to use an EntityBase instance, not casted to any type. The fetch logic won't be able to know its type (to which type it should be casted in order to fetch it again). i.e. its related entities types.

IMHO, Generailization can't work in this situation.

sure it can. i just want the entire entity and all it's children and everything to be just like it was just fetched from the database. the refetch method could know what type the entity is as it's on the entity if it's implemented in the entites themselves. even still, it doesn't need to know this, all it needs to do is tell the entity internally to pretend your new and go back to the db. I'm not sure how all this is implemented internally, but it should be a simple call to whatever methods are called when you loaded the entity in the first place. the entity already knows about it's primary keys etc. just call whatever internal method you called in the first place when I told it to load to start with etc. I can understand if you can't change the refetch method, but can you overload it or add a new method to do this?

Thanks!

arschr
User
Posts: 893
Joined: 14-Dec-2003
# Posted on: 18-Jul-2007 18:26:37   

This has been asked for before.

In adapter, what I've ended up doing is building a manager class that wraps adapter and builds or remembers the prefetch paths needed. I then don't have the adapter do the refetch after the save, I do it myself.

jspanocsi
User
Posts: 145
Joined: 04-Mar-2005
# Posted on: 18-Jul-2007 18:54:48   

arschr wrote:

This has been asked for before.

In adapter, what I've ended up doing is building a manager class that wraps adapter and builds or remembers the prefetch paths needed. I then don't have the adapter do the refetch after the save, I do it myself.

thanks, that's probably what I'll end up doing. we're using ss so it will be easy, i just need the object to be like new.

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39616
Joined: 17-Aug-2003
# Posted on: 19-Jul-2007 10:19:21   

That's indeed what you need. Refetching the 'ent' entity's data isn't what's the problem, as Refetch() does that for you, it's the related entities which have to be rolled back to the previous version as well. This only works if you do one of the following: 1) serialize the whole graph RIGHT BEFORE editing starts to a memory stream which you then use to grab the byte[] buffer of. This byte[] buffer is then kept to roll back to. When you have to roll back to that state, simply create a memorystream from the cached byte[] array, and deserialize that.

or

2) refetch the whole graph again.

Frans Bouma | Lead developer LLBLGen Pro