I'm using GWT 2.4 with RequestFactory but not still everything is clear for me.
In this article author wrote about situation when we used an entity proxy with one instance of RequestContext and want to reuse (edit()) this entity proxy with other instance of RequestContext:
It cannot be edited because it has already a requestContext assigned.
If you want to change it you must retrieve instance of this entity
from server again
But I'm getting no exceptions when I execute this code:
RequestContext newRequest1 = factory.myRequest();
newRequest1.edit(proxy);
RequestContext newRequest2 = factory.myRequest();
newRequest2.edit(proxy);
The problems (exception) described by autor pop up when I run this version:
RequestContext newRequest1 = factory.myRequest();
MyProxy edited = newRequest1.edit(proxy);
RequestContext newRequest2 = factory.myRequest();
newRequest2.edit(edited);
So it seems that only editable copy returned by edit() is directly related with RequestContext instance.
In that case is there something wrong in approoach in which I keep one instance of (uneditable/frozen) proxy in my edit view and each time user clicks "edit" button I edit() it with new fresh RequestContext? Or should I obtain fresh instance of proxy each time too?
Getting new instance of proxy seems a bit awkward for me but I guess reusing one proxy instance may cause some issues related to sending delta of changes to server?
So to rephrase the question: it a good practice to reuse single instance of proxy with multiple RequestContexts?
There's no problem editing the same proxy twice (or more), as long as there's only a single editable instance at a time (your first code snippet should throw; if it's not then it's a bug; it could work if you don't keep references on both the RequestContext and the edited proxy).
Note that RequestFactory sends only the modified properties to the server, but it does so by diff'ing with the non-editable instance passed to edit(); so you should try to use the most recent instance as possible to keep your server-side/persisted data as close to your client-side data as possible (could seem obvious, but can lead to some surprises in practice: if you see foo on the client but have bar on the server, you'll keep the bar on the server-side until you modify the property on the client-side to something other than foo)
Related
How to test this scenario:
I have a user repository that (so far) only has one method: SaveUser.
"SaveUser" is suposed to receive a user as a parameter and save it to the DB using EF 6.
If the user is new (new user is defined by a "Email" that is not present in the database) the method is supposed to insert it, if its not, the method is supposed to only update it.
Technically if this method is called, all business validation are OK, only remaining the act of actually persisting the user
My problem here is: I don't actually want to create a new user or update one every time... this would lead to undesired side effects in the future (let's call it "paper trail")... How do i do it?
Here is the test code:
public void CreateOrUpdateUserTest1()
{
UserDTO dto = new UserDTO();
dto.UniqueId = new Guid("76BCB16B-4AD6-416B-BEF6-388D56217E76");
dto.Name = "CreateOrUpdateUserTest1";
dto.Email = "leo#leo.com";
dto.Created = DateTime.Now;
GeneralRepository repository = new GeneralRepository();
//Now the user should be CREATED on the DB
repository.SaveUser(dto);
dto.Name = "CreateOrUpdateUserTest";
//Now the user should be UPDATED on the DB
repository.SaveUser(dto);
}
Your repository probably needs to invoke some methods of a third party library to actually persist the data. Unit-testing in such case could only make sense if you could mock the third party library and verify and the particular persistence methods are being correctly invoked by your repository. To achieve this, you need to refactor your code.
Otherwise, you can't unit-test this class, but also consider that maybe there is no need to. The third party library responsible for persistence is a different component, so testing if DB storage works correctly with your classes is rather a matter of Integration testing.
Apologies, in advance, if this seems like a duplicate question. This question was the closest I could find, but it doesn't really solve the issues I am facing.
I'm using Entity Framework 5 in an ASP.NET MVC4 application and attempting to implement the Unit of Work pattern.
My unit of work class implements IDisposable and contains a single instance of my DbContext-derived object context class, as well as a number of repositories, each of which derives from a generic base repository class that exposes all the usual repository functionality.
For each HTTP request, Ninject creates a single instance of the Unit of Work class and injects it into the controllers, automatically disposing it when the request is complete.
Since EF5 abstracts away the data storage and Ninject manages the lifetime of the object context, it seems like the perfect way for consuming code to access in-memory entity objects without the need to explcitly manage their persistence. In other words, for optimum separation of concerns, I envisage my controller action methods being able to use and modify repository data without the need to explicitly call SaveChanges afterwards.
My first (naiive) attempt to implement this idea employed a call to SaveChanges within every repository base-class method that modified data. Of course, I soon realized that this is neither performance optimized (especially when making multiple successive calls to the same method), nor does it accommodate situations where an action method directly modifies a property of an object retrieved from a repository.
So, I evolved my design to eliminate these premature calls to SaveChanges and replace them with a single call when the Unit of Work instance is disposed. This seemed like the cleanest implementation of the Unit of Work pattern in MVC, since a unit of work is naturally scoped to a request.
Unfortunately, after building this concept, I discovered its fatal flaw - the fact that objects added to or deleted from a DbContext are not reflected, even locally, until SaveChanges has been called.
So, what are your thoughts on the idea that consuming code should be able to use objects without explicitly persisting them? And, if this idea seems valid, what's the best way to achieve it with EF5?
Many thanks for your suggestions,
Tim
UPDATE: Based on #Wahid's response, I am adding below some test code that shows some of the situations in which it becomes essential for the consuming code to explicitly call SaveChanges:
var unitOfWork = _kernel.Get<IUnitOfWork>();
var terms = unitOfWork.Terms.Entities;
// Purge the table so as to start with a known state
foreach (var term in terms)
{
terms.Remove(term);
}
unitOfWork.SaveChanges();
Assert.AreEqual(0, terms.Count());
// Verify that additions are not even reflected locally until committed.
var created = new Term { Pattern = "Test" };
terms.Add(created);
Assert.AreEqual(0, terms.Count());
// Verify that additions are reflected locally once committed.
unitOfWork.SaveChanges();
Assert.AreEqual(1, terms.Count());
// Verify that property modifications to entities are reflected locally immediately
created.Pattern = "Test2";
var another = terms.Single(term => term.Id == created.Id);
Assert.AreEqual("Test2", another.Pattern);
Assert.True(ReferenceEquals(created, another));
// Verify that queries against property changes fail until committed
Assert.IsNull(terms.FirstOrDefault(term => term.Pattern == "Test2"));
// Verify that queries against property changes work once committed
unitOfWork.SaveChanges();
Assert.NotNull(terms.FirstOrDefault(term => term.Pattern == "Test2"));
// Verify that deletions are not even reflected locally until committed.
terms.Remove(created);
Assert.AreEqual(1, terms.Count());
// Verify that additions are reflected locally once committed.
unitOfWork.SaveChanges();
Assert.AreEqual(0, terms.Count());
First of all SaveChanges should NOT be ever in the repositories at all. Because that's leads you to lose the benefit of UnitOfWork.
Second you need to make a special method to save changes in the UnitOfWork.
And if you want to call this method automatically then you may fine some other solution like ActionFilter or maybe by making all your Controllers inherits from BaseController class and handle the SaveChanges in it.
Anyway the UnitOfWork should always have SaveChanges method.
I have problem to understand what does Request factory send to server. I have a method
Request<NodeProxy> persist(NodeProxy node)
NodeProxy is an Object from tree like structure (has child nodes and one parent node, all of type NodeProxy). I'v change only one attribute in the node and called persists.
The question now is what gets send to the server?
In the dock here https://developers.google.com/web-toolkit/doc/latest/DevGuideRequestFactory
there is:
"On the client side, RequestFactory keeps track of objects that have been modified and sends only changes to the server, which results in very lightweight network payloads."
In the same dock, in the chapter Entity Relationships, there is also this:
"RequestFactory automatically sends the whole object graph in a single request."
And I'm wondering how should I understand this.
My problem:
My tree structure can get quete big, lets say 50 nodes. The problem is that for update of one attribute the method
public IEntity find(Class<? extends IEntity> clazz, String id)
in the class
public class BaseEntityLocator extends Locator<IEntity, String>
gets called for each object in the graph which is not acceptable.
Thank you in advance.
The problem you're facing is that RequestFactory automatically edit()s proxies when getting properties, and there's a bug when constructing the request payload that makes the whole graph of proxies to be implicitly edited that way, even if you didn't call the getter yourself.
That bug has many repercussions, including false-positives in RequestContext's isChanged(): http://code.google.com/p/google-web-toolkit/issues/detail?id=5952
I have great hopes that this will be fixed in GWT 2.5 (due in the next weeks).
"core" refers to the initial piece of the application that is loaded.
In order to bind url to places, GWT uses PlaceTokenizer<P extends Place>. When loading the application from the url, it calls the method P getPlace(String token) to retrieve a new instance of the place to call.
due to the asynchronous nature of code splitting, I can't create the place inside a runAsync in this method. So I have to put all the places of my app in the core.
To link places to activity, GWT callsActivity getActivity(Place place) (from com.google.gwt.activity.shared.ActivityMapper) to retrieve a new instance of the activity.
Once again, i have to put all my activities in the core.
Here's what I want to try: Write a custom com.google.gwt.place.shared.Delegate that
bind itself on PlaceChangeRequestEvent. If the AppPiece corresponding to the requestedPlace isn't loaded, it calls event.setWarning(NEED_TO_LOAD_MODULE)
in the confirm(String message) method, always return false when the message equals NEED_TO_LOAD_MODULE (so it doesn't bother the user), and load the module via RunAsync.
Once the module is loaded, call goTo(requestedPlace)
Each AppPiece of my application contains a bunch of activies and the corresponding views. Since the mappers are only called when PlaceChangeEventis fired, i could generate a new instance of my activity via AppPiece.getSomeActivityInstance().
I'm pretty sure this will work, but what bother me is that
Finding wich AppPiece to load depending on the requestedPlace will force me to write code that will be very similar to my mappers
I would like to have my places inside the corresponding AppPiece
Overriding Delegate for this purpose is tricky, and I'm looking for a better solution
You don't have to put all your activities in the core (as you call it): while an Activity instance is retrieved synchronously, it's allowed to start asynchronously. This is where you'd put your GWT.runAsync call.
See http://code.google.com/p/google-web-toolkit/issues/detail?id=5129 and https://groups.google.com/d/topic/google-web-toolkit/8_P_d4aT-0E/discussion
I am developing using Entity Framework and WPF, and I am encountering some errors and I don't know why. When saving a record (using a BackgroundWorker), I set the entities change tracker to nothing (null), attach the record to a new disposable context, save it, detach, and dispose of the context.
Saving a record fires and event in theMainViewModel of the program that the other ViewModels (including the one that is saving) need to refresh their entities to reflect changes.
Private Sub _saveRecordWorker_DoWork(ByVal sender As Object, ByVal e As System.ComponentModel.DoWorkEventArgs) Handles _saveRecordWorker.DoWork
Using MyContext As New RVShippingEntities
Dim MyShipment = CType(ShipmentRecord, IEntityWithChangeTracker)
MyShipment.SetChangeTracker(Nothing)
MyContext.Attach(MyShipment)
MyContext.Detach(ShipmentRecord)
End Using
End Sub
The Refresh background worker is similar, but it has a Do While block to keep it from interfering with the save worker (which doesn't appear to be working; hence the post). When I save (and it subsequently refreshes) I get the following error:
The calling thread cannot access this object because a different thread owns it.
I thought that with theDoWhile block, it would wait (and when I step through it does) until the save thread finished, and all would be good. But it would seem that something (either the main thread or the save thread) is still doing something that is interfering.
Is there a better way of doing this? Am I doing it in a goofy kludgey fashion? Any help would be appreciated.
(Apparently Firefox recognized kludgey as a word. Interesting)
So, 3+ months and nary an exception so far in relation to Entity Framework. I am going to call this the answer.
Parent Views (in my case Company, Customer, Shipment) have a context which is passed to child Views as necessary (Addresses, Phone Nums, Email Addresses, for Company and Customer; Packages, Contents, for Shipments). Anytime a context can't save changes or what have you (db disconnection is most common cause), the context is disposed, a new one instanced, the entities are re-attached, set to modified (based on custom change tracking which I do for UI), and changes are saved.