Lets assume that I have the following object Model with me (you are free to change it in a way you like, my interest is only mapping efficiently),
public class Product{
private String someAttribute;
//...
}
// A Seller who has a lot of products to sell, More than one Seller can sell the same Product
public class Seller{
private List<Product> products;
//...
}
public class Offer{
// who is offering
private Seller seller;
// multiple products can make an offer
private List<Product> products;
// pricing related
private Price price;
//...
}
I want to write a web app, which will perform, read/write/search on these objects and consider the point of entry could be any one of them.
Following are my queries,-
- What is the design pattern, that I shall use ? I guess some kind of Adapter pattern?
While storing Seller objects, should I store the references of Product objects as well? or just the keys ? What I mean is should I convert the Seller class into following,
public class Seller { private List productKeys; }
If I want to write a scalable and maintainable application, I think there should be some nice way design my Application in layered architecture. Is there some example for that or some already used pattern? e.g. Some kind of JSP --> Service --> DAO --> dataStore ? Examples would be really appreciated.
I went through the AppEngineSDK for java as well, but did not hit an example for the same. help in answers or pointers is truly appreciated.
With NoSQL databases (such as GAE Datastore) you should be thinking in terms of data access model, not data storage model. I.e. you should be thinking how you will be accessing data and how you will organize data so that access is most efficient (= faster and cheaper).
Unfortunately this often goes against OOP principles and Datastore "schema" (there is no Datastore schema, you realize that, don't you?) does not fit nicely into Java OOP paradigm.
A way to achieve this is to de-normalize data, meaning that you write data (as much as possible) in one big record, which also means that data is redundant.
Now, since you can not put all data in one record, you need to make several concessions. To do this you must decide:
From your model I'd guess that Product & Seller would not change much, but Offer will be often created, right? Try to design so that you minimize number of reads/writes - start with data that is used most and organise schema so that you get/put most of data with minimum number of reads/writes.
Trying to answer your questions:
Just create your Service layer, where you perform basic CRUD functions (add/update/delete/find Seller/Product/etc) and higher-level business functions (create Offer for Seller with Products, etc..). DAOs are PITA, so you should try to work with POJOs as much as possible - use Objectify. In this case you could do away with Adapter pattern.
If by references you meant IDs (long, Long or String) then you should go with keys: keys are a combination of parent keys, kind and ID. Keys are guaranteed to be unique, while IDs are not (they are unique only if you are not using Entity Groups). Also, with objectify, keys are type-safe, while IDs are not.
As described in 1., layered approach is the way to go. Do try to avoid DAOs though - they require a lot of manual work and as such are a source of errors.
I would take a look at objectify: http://code.google.com/p/objectify-appengine/
In general the rule of thumb with data access in appengine is to avoid as many "joins" as possible. Fetching large (even massive) datasets from a single table is very cheap in appengine, but fetching from many smaller related sources of data is very expensive. So in your example you would want to consider storing products as embedded collections in the seller table if you can get away with doing that.
HTH
Rick