Skip to content

Latest commit

 

History

History
190 lines (124 loc) · 6.13 KB

relation_syntax_one.textile

File metadata and controls

190 lines (124 loc) · 6.13 KB

This syntax is only available for GAE implementation for the time being but will be ported soon to other impl

The following code samples can be found in samples dir

Description

This is a new syntax to represent:

  • the relation from the owner/aggregator entity to the child/owned entity in an One2XXX relation
  • the owner side in an owned relation
  • the aggregator side in an aggregated relation

Keep in mind that Siena just manages the relation but not the objects themselves

Siena DO

  • manage the relation but not the full life-cycle of related entities.
  • manage relation change from one related entity to another one.
  • auto-insert the related entity at the same time as the parent (or when updating it) if not done yet.
  • lazy-load the related entity only when required.
  • delete-cascade the aggregated entities because an aggregated entity can’t exist outside its aggregator. This is the ONLY accepted delete cascade.

Siena DOESN’T

  • manage the updates of data within the related entity. You must save it yourself.
  • delete the owned entities when you delete the owner since an owned entity can change owner.


Here is the owner model:

public class OwnerModel {
...
	@Owned(mappingBy="owner")
	public One<ChildModel> child;	
...
}

Here is the child model:

public class ChildModel {
...
	public OwnerModel owner;	
...
}

Note On the child side, the owner field is just written as a simple reference to the owner without any One<T>. Why? because, on the owned entity side, the owner is just referenced by its id/key.

Using the old notation Query<T>, the One<T> is equivalent to:

public class OwnerModel {
...
	@Filter("owner")
	public Query<ChildModel> child;	
...
}

Note Yet, you should take care of the unicity of the child by yourself.


Here is the aggregator model:

public class AggregatorModel {
...
	@Aggregated
	public One<ChildModel> child;	
...
}

Here is the aggregated model:

public class AggregatedModel {
...
...
}

Note On the aggregated side, there is no reference to the aggregator because an aggregated entity shall not be aware of its aggregator: it’s a part of it but it was not necessarily meant to be.
It’s very useful because you don’t need to foresee your model will be aggregated while designing it and you can aggregate any model.

The aggregator reference is managed by Siena itself and you don’t have to deal with it neither declare it in your model.

Note Nevertheless, if you absolutely want to access your own aggregator, it’s possible. Go to the aggregated relation page.


The 3 importants functions of One<T> are:

  • void set(T obj) : a setter to change the OneToXXX related child
  • T get() : a getter to get the current child of the OneToXXX relation
  • One<T> forceSync() : a useful function to force to resynchronization of the child with the DB when you want to be sure you get the latest version.
Dog pluto = new Dog("Pluto");
		
Person tom = new Person("Tom");
// associates the child entitys
tom.dog.set(pluto);
tom.save(); // or insert(), it's exactly the same behavior

Note You don’t have to insert the child object as Siena inserts it at the same time as the parent (if the child was not inserted yet).


Person tom = Person.getByName("Tom");
// here tom's dog is not yet loaded and you can load it through One<T>.get()
Dog pluto = tom.dog.get();

Note tom.dog is a One<Dog> so you need to use get() to access the real object


Person tom = Person.getByName("Tom");
// creates a new dog
Dog medor = new Dog("Medor");
// associates the new dog to the master
tom.dog.set(medor);
// inserts medor, changes the relation and updates tom
tom.update();

// OWNED RELATION ONLY: proves pluto is no more the dog of tom
Dog pluto = Dog.getByName("Pluto");
assert(pluto.master == null);

Note In an aggregated relation, when you change the target of the relation and updates the parent, the previous related entity is deleted as it can’t exist outside its parent aggregator.


Person tom = Person.getByName("Tom");
// gets current pluto
Dog pluto = tom.dog.get();
...
// some time later, you want to be sure to have the latest version
Dog pluto = tom.dog.forceSync().get();


Person tom = Person.getByName("Tom");
Dog pluto = tom.dog.get();
pluto.name = "Pluto2";

tom.save(); // THIS DOESN'T UPDATE PLUTO
assert(pluto.name.equals("Pluto"));
pluto.save(); // THIS SAVE PLUTO
assert(pluto.name.equals("Pluto2"));
 Car peugeot = Car.getByName("Peugeot");
Motor motor = car.motor.get();
Motor newmotor = new Motor("newmotor");
car.motor.set(newmotor);

peugeot.update();
// motor is also deleted
motor.get(); // throws SienaException()
Car peugeot = Car.getByName("Peugeot");
Motor motor = car.motor.get();

peugeot.delete();
// motor is also deleted