0
votes

my app is using objectify. i'm really new to NoSql .

i have a data model like this. pay no attention to lack of getters and setters, lack of builder pattern, etc. is just an example.

as you can see, ReallyWeirdCar is the root of a quite deep object graph.

now, suppose i build a ReallyWeirdCar object completely in memory using the given method.

also, assume datastore is completely empty.

how do i save that object using objectify ?

is it ofy().save().entity(rwc1) enough to save the entire object graph in one shot ?

how do i persist relationships like this ?

also, would you consider this a "good"(performant) model if most of the time i'm executing queries like "find all the cars that were solicited by customer john"

thx in advance

    @Entity
    class ReallyWeirdCar {

    @Id
    public String id;

    public String name;

    @Load
    public Ref<Engine> e1;

    @Load
    public Ref<Engine> e2;

    // a reference to the customer who solicited the construction of this car
    @Index
    @Load
    public Ref<Customer> customer;

}

    @Entity      
    class Customer {

    @Id
    public String id;

    public String name;
}

@Entity
class Engine {

    @Id
    public String id;

    public String name;

    @Load
    public Ref<List<Carburetor>> ecs;

}

@Entity
class Carburetor {

    @Id
    public String id;

    public String name;

    @Load
    public Ref<Manufacturer> manufacturer;

}

@Entity
class Manufacturer {

    @Id
    public String id;

    public String name;

}




 // inside some service 
 public buildAndPersistCar() { 

    Customer cust1 = new Customer("cust1", "customer1"); 

    Manufacturer m1 = new Manufacturer("m1", "manufacturer1");

    Carburetor c1 = new Carburetor("carb1", "carburetor1", m1);
    Carburetor c2 = new Carburetor("carb2", "carburetor2", m1);
    Carburetor c3 = new Carburetor("carb3", "carburetor3", m1); 
    Carburetor c4 = new Carburetor("carb4", "carburetor4", m1); 

    Engine e1 = new Engine("e1", "engine1", Arrays.asList(c1,c2)); 
    Engine e2 = new Engine("e2", "engine2", Arrays.asList(c3,c4)));

    ReallyWeirdCar rwc1 = new ReallyWeirdCar("rwc1", "reallyweirdcar1", e1, e2, cust1);     

    // what do i do here ???? 
    // how do i persist rwc1 ???



}
1

1 Answers

1
votes

There is no concept of "cascading save" in Objectify. If you want to save N entities, you must save them all explicitly. What You Save Is What You Save.

From a performance perspective, this looks suboptimal. The GAE datastore likes fatter coarse-grained entities; your example requires four rounds of fetching just to get to the Manufacturer. If this is a genuinely accurate model, then you may wish to live with it; four rounds of fetching won't kill you, especially of most of the entities are in memcache. But if you can denormalize the model (say, embedding Carburetor in Engine), you can probably make it faster.

This is exactly the same problem you are faced with in relational databases (normalize or denormalize). It's actually easier with Objectify because Objectify is smart about "rounds" of batch fetching; you'll get four API calls instead of ~N^4 API calls. But it would still be painful to load a whole engine full of thousands of components.