- Home
- LLBLGen Pro
- LLBLGen Pro Runtime Framework
Serialization question
Joined: 30-Jun-2005
Your documentation states:
The Context class works with instances of entity classes. This means that when you pass an entity instance using remoting or webservices to a server which then returns it back after processing, you won't reference the same instance of the entity you sent to the server.
This is a bit scary to me Does this mean that an entity's reference is reset when an adapter.save happens across remoting? Does this only happen when using a Context object, or all the time?
If the answer is that the reference does get reset, what happens to the bindings to UI controls (that the entity's properties are bound to)? What happens to other objects that are relying on this entity's events (like onFieldChange)?
You have in a remoting scenario for example 2 processes: client and server. Server creates an entity instance and sends it via remoting to the client. When this happens, the instance isn't send, but data which will result in exactly the same copy on the other end. So on the client, a NEW instance is created and the data received from the server is placed inside this instance.
At that moment you have 2 instances: on the server and on the client. This is what's called 'call by value' or 'passed by value'. Even though they represent the same ENTITY, the entity OBJECTS (or 'container' in which the entity's data is stored in) are different.
So when you then decide to destroy the server's instance (because it goes out of scope), the client still has its version. When the client places it inside a Context object, and later on sends it back to the server, the process is the same: data is send across the wire, a new entity instance is created on the server and the data received from the client is placed inside that instance. That instance is then for example saved and updated and send back to the client, which process is described above.
After that, you have 2 instances with data which represent the same entity, for example customer with PK "CHOPS".
The remark was to make the reader aware that remoting seems like it sends instances over, but in fact data is send and new instances are recreated when data arrives.
Joined: 30-Jun-2005
Otis wrote:
You have in a remoting scenario for example 2 processes: client and server. Server creates an entity instance and sends it via remoting to the client. When this happens, the instance isn't send, but data which will result in exactly the same copy on the other end. So on the client, a NEW instance is created and the data received from the server is placed inside this instance.
At that moment you have 2 instances: on the server and on the client. This is what's called 'call by value' or 'passed by value'. Even though they represent the same ENTITY, the entity OBJECTS (or 'container' in which the entity's data is stored in) are different.
So when you then decide to destroy the server's instance (because it goes out of scope), the client still has its version. When the client places it inside a Context object, and later on sends it back to the server, the process is the same: data is send across the wire, a new entity instance is created on the server and the data received from the client is placed inside that instance. That instance is then for example saved and updated and send back to the client, which process is described above.
After that, you have 2 instances with data which represent the same entity, for example customer with PK "CHOPS".
The remark was to make the reader aware that remoting seems like it sends instances over, but in fact data is send and new instances are recreated when data arrives.
I'm still having a bit of trouble following this. I can understand that there are really two instances of customer "CHOPS" with one on the server and one on the client, but when this happens:
Client.callServerFetch(customer c)
is the reference to c lost? For example, would the following result in an error?:
Client: Dim c as new customer(c) Dim d as customer = c server_fetch(c) msgbox(d.firstname)
Would it result in an error if c was placed in a context?
mikeg22 wrote:
Otis wrote:
You have in a remoting scenario for example 2 processes: client and server. Server creates an entity instance and sends it via remoting to the client. When this happens, the instance isn't send, but data which will result in exactly the same copy on the other end. So on the client, a NEW instance is created and the data received from the server is placed inside this instance.
At that moment you have 2 instances: on the server and on the client. This is what's called 'call by value' or 'passed by value'. Even though they represent the same ENTITY, the entity OBJECTS (or 'container' in which the entity's data is stored in) are different.
So when you then decide to destroy the server's instance (because it goes out of scope), the client still has its version. When the client places it inside a Context object, and later on sends it back to the server, the process is the same: data is send across the wire, a new entity instance is created on the server and the data received from the client is placed inside that instance. That instance is then for example saved and updated and send back to the client, which process is described above.
After that, you have 2 instances with data which represent the same entity, for example customer with PK "CHOPS".
The remark was to make the reader aware that remoting seems like it sends instances over, but in fact data is send and new instances are recreated when data arrives.
I'm still having a bit of trouble following this. I can understand that there are really two instances of customer "CHOPS" with one on the server and one on the client, but when this happens:
Client.callServerFetch(customer c)
is the reference to c lost? For example, would the following result in an error?:
Client: Dim c as new customer(c) Dim d as customer = c server_fetch(c) msgbox(d.firstname)
Would it result in an error if c was placed in a context?
d will point to your first instance, and I don't know to what c will point, as server_fetch(c) doesnt make sense: Your example shows you want to pass in an INSTANCE to the server and tell it to fetch the data INTO that object. BUt that's not how distributed applications work. You tell the server to get an entity with the PK values you pass in and you receive that entity. This is because the entity objects are passed by value, not by reference.
A context object is just a local uniquing cache. This means that if you want to use in a given process (e.g. client, server, but not client + server! these are 2 different processes/appdomains!) the same instance which contains a given entity, you use a context to get that instance.
So, for example: 1) you first create a context on client 2) requesting customer 'CHOPS'. Check if the context has the instance, using Get(factory, pkvalue). If it returns a new entity, it wasn't there and proceed with 3). If it was, you get the instance of 'CHOPS' as it is known on the CLIENT. You can then use that instance as nothing happened. You then thus don't go to the server to fetch it. It's good practise to fetch the data once in a while, depending on the data 3) fetch CHOPS from the server and add the entity to the context.
Joined: 30-Jun-2005
Otis wrote:
mikeg22 wrote:
Otis wrote:
You have in a remoting scenario for example 2 processes: client and server. Server creates an entity instance and sends it via remoting to the client. When this happens, the instance isn't send, but data which will result in exactly the same copy on the other end. So on the client, a NEW instance is created and the data received from the server is placed inside this instance.
At that moment you have 2 instances: on the server and on the client. This is what's called 'call by value' or 'passed by value'. Even though they represent the same ENTITY, the entity OBJECTS (or 'container' in which the entity's data is stored in) are different.
So when you then decide to destroy the server's instance (because it goes out of scope), the client still has its version. When the client places it inside a Context object, and later on sends it back to the server, the process is the same: data is send across the wire, a new entity instance is created on the server and the data received from the client is placed inside that instance. That instance is then for example saved and updated and send back to the client, which process is described above.
After that, you have 2 instances with data which represent the same entity, for example customer with PK "CHOPS".
The remark was to make the reader aware that remoting seems like it sends instances over, but in fact data is send and new instances are recreated when data arrives.
I'm still having a bit of trouble following this. I can understand that there are really two instances of customer "CHOPS" with one on the server and one on the client, but when this happens:
Client.callServerFetch(customer c)
is the reference to c lost? For example, would the following result in an error?:
Client: Dim c as new customer(c) Dim d as customer = c server_fetch(c) msgbox(d.firstname)
Would it result in an error if c was placed in a context?
d will point to your first instance, and I don't know to what c will point, as server_fetch(c) doesnt make sense: Your example shows you want to pass in an INSTANCE to the server and tell it to fetch the data INTO that object. BUt that's not how distributed applications work. You tell the server to get an entity with the PK values you pass in and you receive that entity. This is because the entity objects are passed by value, not by reference.
A context object is just a local uniquing cache. This means that if you want to use in a given process (e.g. client, server, but not client + server! these are 2 different processes/appdomains!) the same instance which contains a given entity, you use a context to get that instance.
So, for example: 1) you first create a context on client 2) requesting customer 'CHOPS'. Check if the context has the instance, using Get(factory, pkvalue). If it returns a new entity, it wasn't there and proceed with 3). If it was, you get the instance of 'CHOPS' as it is known on the CLIENT. You can then use that instance as nothing happened. You then thus don't go to the server to fetch it. It's good practise to fetch the data once in a while, depending on the data 3) fetch CHOPS from the server and add the entity to the context.
Ah...ok, I forgot something in my example... Client: Dim c as new customer("CHOPS") Dim d as customer = c server_fetch(c) msgbox(d.firstname)
Will the "d" reference point to an object that has data filled in by the server?
Joined: 30-Jun-2005
Otis wrote:
No, it will simply display an empty string. c is pointing to a new entity OBJECT, not the same as d is pointing to.
So, if "c" was bound to an GUI element, doing an update on "c" would mean I would have to rebind "c" to that same GUI element, and all references to "c" would have to be reset to point to "c" again?
Ouch...
it's the way distributed applications work. You won't run into this normally, as the communication with the server is done first BEFORE the gui actions take place, then the gui actions take place and then, when the work is done, the results are gathered and the server is contacted again to persist data/changes. Doing a REFETCH of an entity which is bound to a gui isn't that likely.
You could use a context to solve this though. First fetch the entity E and assign it to the variable c, add it to your context object mycontext. Bind it to the gui. Then, when you have to refetch it, refetch it in another entity, like 'd'. Then, do d = myContext.Get(d);. This will set d to the instance referenced by c, and update it with the values read from the server. c will thus also have these updated values. So c can be kept bound to the controls, and d is used to update the data in the entity, using the context.