GAE, change an class for a persistent object - google-app-engine

I have a web application with some data in its datastore. I have just finished another version of it, in which i changed one of the persistent classes. Basically, there is a class called "Node" (which represents a node in a hierarchy tree), that used to have it's author as a
private CmsUser author;
and now it stores its author as
private Key author.
When i deployed that second version to the server (as another version), it didnt work (which is predictable).
Is there any way to make it work? Or do i have to create another entity instead of the Node thing and write a piece of code that would change all my old nodes into new ones?
Thanks.

You will have to write some code that loads each Node in its old form, then saves it in the new form.
Since it looks like you are using java, you can do this with the low level API. If you were using Python, there is a trick you can do with Expando. See here
You might want to try the new Mapper API to handle looping through all your entities.

Related

Google App Engine Push Task - Using the DeferredTasks instead of a worker service warning

There is a warning about using DeferredTask in the documentation that says:
Warning: While the DeferredTask API is a convenient way to handle
serialization, you have to carefully control the serialization
compatibility of objects passed into payload methods. Careful control
is necessary because unprocessed objects remain in the task queue,
even after the application code is updated. Tasks based on outdated
application code will not deserialize properly when the task is
decoded with new revisions of the application.
I don't understand this. What does it mean "careful control"? Does anyone have an example of how one can write a poor DefeferredTask?
Java serialization follows certain rules that you need to be aware of. By default, any change to a Java class "breaks" serialization; objects serialized with the old class cannot be deserialized with the new class.
If you declare a serialVersionUID in your class (and don't change the value), then deserialization will be allowed even as you change the class. It will do what you normally expect if you're used to serializing to/from JSON and adding/removing fields to/from your classes. Ie, fields removed from classes will leave data ignored and new fields added will be have default values.
Some people hate Java serialization and some people love it. It's useful, and very convenient when working with the task queue. If you always declare a serialVersionUID you'll probably be fine... most mistakes will cause exceptions when you try to serialize data, and you'll figure those pretty quickly.

EF Code First / WPF Application architecture guidance needed

I'm working on a 2-tier WPF/EF Code First application. I did a lot of googling but couldn't find a sample implementation of what I was looking for... was hoping that someone on this forum could help me out. Here are the requirements:
On Application Start up
Open a DBContext
Cache the reference data in various maps/lists when the application starts
Close Context.
When user opens a form
Open a DBContext (I'm using UnitOfWork pattern here)
Fetch a fresh copy of Entity from context for Editing.
Call SaveChanges() when Save button is hit.
Close the Context.
The problem manifests when I use an object from Cache to change a navigation property.
e.g. use a drop down (backed by cache which was created using a different DBContext) to set Department navigation property.
The UnitOfWork either throws an exception saying entity was loaded in another DBContext (When Department is lazy loaded DynamicProxy) or inserts a new row in Department table.
I couldn't find even a single example where reference data was being cached... I can't believe that no one came across this issue. Either I'm not looking in the right place or not using the right keywords.
I hope this is doable using EF. I'd appreciate if you can share your experiences or post some references.
I'm kinda new to this so would like to avoid using too many frameworks and just stick to POCO with WPF/EF stack.
Try to attach your cached item (probably, you'd make a clone before attaching):
var existingUnicorn = GetMyExistingUnicorn();
using (var context = new UnicornsContext())
{
context.Unicorns.Attach(existingUnicorn);
context.SaveChanges();
}
Refer to Using DbContext... article.
You mention you are using WPF for this, in that case you don't necessarily have to open a new DBContext every time you want to interact with the domain layer. (Apologies if this goes against UoW that you are keen on using)
Personally I have been using code-first development for a desktop application, and I have found that pooling the contexts (and therefore the connection) prevents this problem, and hasn't led to any problems thus far.
In principle, as soon as the application is launched, a main Context object is opened for the main UI thread, and stays open throughout the duration of the application lifetime. It is stored statically, and is retrieved by any Repository class when they are used.
For multi-threading scenarios, any background threads are free to open up additional contexts and use them in Repositories to prevent any race conditions.
If you were to adopt this approach, you would find that as all repositories share the same context, there are no issues arising from object context tracking.
I ended up defining int foreign key property in addition to navigation.
In my application I only modify the int property and use the navigation property for displaying the details (read only controls).
While this works it makes the application a little fragile and sometimes inconsistent.
although this blog claims that the FK & Navi properties are synced by EF but I couldn't get it to work.
http://coding.abel.nu/2012/03/ef-code-first-navigation-properties-and-foreign-keys

Where/how should the database code go in a class/application?

So, I don't know if the question is explicit enough, but here's my problem:
I am writing a small application in VB.Net, that retrieves information from a website and present it to the user. Basically, I have written a class, which has a Get(URL) method which retrieves the webpage, reads it and populates the various Properties (Read-only) of the object.
This class works OK.
Now, I would like to store that information in a Database (I'm using Access for now), so that I can read the data from the DB, if the class gets called for a known URL. As I'm fairly new to OOP and completely new to DB usage in desktop applications (no problems in designing the DB though), I am not sure on how to proceed:
Should I put the database code in my existing class?
Should I create an extended class based on the existing one, adding the DB code?
Should I create a completely different class for the DB data and put the switch logic (read from DB or from web) in my application?
...
I realize that my question may sound silly to the most experienced of you, but I'm new to this and I would really like to learn how to do things the right way the first time!!!
Thanks!
This is what I would do:
Create a new class for the database code, and create an
interface for it that it implements.
Then create another class that has the code to fetch the web data. Make it implement the same interface.
Now you can subsitute either class to do your data access from your controller class.
Also, I usually put database and data access in separate projects from my service and ui classes, which are in their own classes, but that might be overkill for your situation.
If you'd like to read more on the subject, look up n-tier application design. The tier you're talking about here is data access.
http://en.wikipedia.org/wiki/Data_access_layer

What is the correct way to solve the ambiguous reference issue in WCF services?

Project Structure
I have a silverlight project SLProj, that references a silverlight class library project called ServiceClients. ServiceClients has two wcf service references, Svc1.svc and Svc2.svc. Both Svc1.svc and Svc2.svc are in two different WCF projects which use the same set of DataContracts which are again in a different class library project called MyDataContracts.dll.
Problem description
Now in my ServiceClients project I get an ambiguous reference issue when I need to use a datacontract class which is present in both the service references. If this were a winforms or webforms project, I could reference the MyDataContracts.dll and reuse the common types. But since, this MyDataContracts.dll was built using a non silverlight class library, it can't be referenced in the silverlight project
Workaround...
I am not sure if this below is the best method to go about taking care of this issue. Can anybody let me know if there is a cleaner way to solve this problem, or is this the best way we have so far?
create a single service reference.
click the 'show all files' button in the solution explorer
drill into the service reference and find Reference.svcmap and open it
find the MetadataSources section
add a second line to include the address to your second service. for example:
MetadataSource Address="http://address1.svc" Protocol="http" SourceId="1"
MetadataSource Address="http://address2.svc" Protocol="http" SourceId="2"
save, close, and update service reference.
Use Automapper
Map the DataContracts with AutoMapper.
You will have to invest some time in understanding AutoMapper and reworking your application. Also AutoMapper adds overhead because all data objects will be mapped. But first you will have a clean solution without hacks and second you gain a decoupled and simple data object layer just for your client. Once done you can forget the mapping but you stay flexible for future changes.
If you never have worked with Automapper it's important to play around with it before starting. Automapper is special and needs some time to familiarise with it.
So there. These are the rough steps:
1. Create a subdirectory and sub-namespace Data and copy the DataContracts. Remove the attributes and properties your client doesn't need because these mapped classes live only in your client. You can also change some types or flatten some complex properties.
2. Create an AutoMapperInit.cs like described at Automapper (read the Getting Started Guide). Use the conflicting references like this:
using ref1 = YourProjectServiceReference1;
using ref2 = YourProjectServiceReference2;
3. Wrap the service client like this:
Example GetExample() {
return AutoMapper.Map<ref1.Example, Example>(ref1.YourService.GetExample());
}
The wrapper also needs the same using directives as in step 2.
4. In this wrapper add a static initializer like this (assuming your wrapper class is called Wrapper):
static Wrapper() {
AutoMapperInit.CreateMaps();
}
5. Omit service references in the client and use using YourClient.Data;, the namespace you created in step 1.
Your client is now decoupled from the service and you don't have conflicts anymore.
Disclaimer: I am not affiliated with AutoMapper. I just used it in a project with a similar problem and am happy with it and wanted to share my experience.
Your workaround is actually quite OK. We've used it in several projects like this with 3 service references. It is actually a workaround for the IDE which for some reason only allows to select one service to create a service reference at a time.
Another thing you could try-out is to multi-target your shared contract to .NET and Silverlight, using the same codebase. Details on how to do such thing is described in http://10rem.net/blog/2009/07/13/sharing-entities-between-wcf-and-silverlight. Might be more work but feel less hacky.

How to setup EXTJS4 store for CRUD Couch DB?

How to calibrate Extjs 4 store for simple CRUD from/to couchDb?
There is a demo project that was put together for our last Austin Sencha meetup that shows connecting Ext 4 to both Couch and MongoDB:
https://github.com/coreybutler/JSAppStack
Specifically this class will probably help you get started.
I have developed a library called SenchaCouch to make it easy to use CouchDB as the sole server for hosting both application code and data. Check it out at https://github.com/srfarley/sencha-couch.
I'd like to point out that to fully implement CRUD capabilities with the demo require some modification. CouchDB requires you to append revisions for any update/delete operation. This can also cause some issues with the field attributes in the Ext REST proxy. There is a project called mvcCouch that would be worth taking a look at. This project references a plugin that should help with full CRUD operations against CouchDB.
You'll find a number of subtleties in ExtJS 4's REST proxy that can slow you down. this brief post summarises the major ones:
In your Model class, you have to either define a hardcoded 'id' property or use 'idProperty' to specify one column as 'id'.
You server side code needs to return the entire updated record(s) to the browser. CouchDB normally returns only an _id and _rev, so you'll have to find a way to get the entire document on your own.
Be aware that the format of the record in the "data" must be JSON-formatted.
Be sure to implemented at least one Validator in your Model class because, in ExtJS source code AbstractStore.js, you can find the following code, which may always return true for a new created record in RowEditing plugin when the store is set as autoSync = true.
filterNew: function(item) {
// only want phantom records that are valid
return item.phantom === true && item.isValid();
},
This last item is, in my opinion, a design bug. The isValid() function should by rights return true by default, and rely on the developer to throw an error if problems occur.
The end result is that unless you have a validator for every field, the updates never get sent to CouchDB. You won't see any error thrown, it will just do nothing.
I just released two update libs for Sencha Touch and CouchDB respecively(based on S. Farley's previous work). They support nested data writing and basic CRUD.
https://github.com/rwilliams/sencha-couchdb-extjs
https://github.com/rwilliams/sencha-couchdb-touch

Resources