Skip to content

Latest commit

 

History

History
192 lines (135 loc) · 5.56 KB

inheritance.textile

File metadata and controls

192 lines (135 loc) · 5.56 KB

Siena Inheritance

In Siena, you can inherit a model from another one.

Inheritance Code sample

Here is a superclass:

@Table("people_long_auto_model")
public class PersonLongAutoIDModel extends Model {

	@Id(Generator.AUTO_INCREMENT)
	public Long id;
	
	@Column("first_name") @Max(100)
	public String firstName;
	
	@Column("last_name") @Max(100)
	public String lastName;
	
	@Max(100)
	public String city;
	
	public int n;
	
	...
}

Now here is a subclass extending superclass:

@Table("people_long_auto_extended")
public class PersonLongAutoIDExtended extends PersonLongAutoIDModel {

	@Max(100)
	public String dogName;
	
	@Column("boss") @Index("boss_index")
	public PersonLongAutoIDModel boss;
    
	@Filter("boss")
	public siena.Query<PersonLongAutoIDExtendedFilter> employees;
           
	@Embedded
	public Image profileImage;
    
	@Embedded
	public List<Image> otherImages;

	@Embedded
	public Map<String, Image> stillImages;
    
	@EmbeddedMap
	public static class Image {
		public String filename;
		public String title;
	}
    
    ...
}

How inheritance is managed by Siena?

Hibernate proposes 3 main modes to manage inheritance (see here)

  • the Table per class hierarchy mode: the fields of the superclass and subclassES are stored within the same table. You have a big table with lots of fields.
  • the Table per subclass mode: each subclass has its own table containing only the fields of the corresponding class with a primary key association to subclass table.
  • the ___Table per concrete subclass__ mode: the superclass has its own table (if required) with the fields of the superclass and each subclass has also its own table containing the fields of both subclass and superclass.

Siena is not meant to mimic Hibernate in any case and as the inheritance feature is still young in Siena, we decided to keep it as simple and straightforward as possible.
Thus, Siena implements only the Table per concrete subclass mode for the time being.

So for previous code samples, Siena will create 2 tables:

  • Table people_long_auto_model
  • Table people_long_auto_extended
Table people_long_auto_model Table people_long_auto_extended
id id
firstName firstName
lastName lastName
city city
n n
dogName
boss
profileImage
stillImages
otherImages

Note The people_long_auto_extended table contains the fields of the superclass and its own fields.

Note The field employees doesn’t appear in people_long_auto_extended table as it’s an “automatic query” which shall not represented in the DB (child entities are linked to parent through the boss field.

The SuperClass as a simple field container using abstract modifier

Sometimes you will need to create a superclass that is just a container class containing fields but not represented in the DB by any table.
This is useful when you want to put some generic fields in your superclass and reuse them in several subclasses.
It is possible to do this is in Siena by just using the class modifier abstract

public abstract PersonLongAutoIDModel extends Model {

	@Id(Generator.AUTO_INCREMENT)
	public Long id;
	
	@Column("first_name") @Max(100)
	public String firstName;
	
	@Column("last_name") @Max(100)
	public String lastName;
	
	@Max(100)
	public String city;
	
	public int n;
	
	...
}

Note the @Table annotation is not required as it won’t be interpreted by Siena.

In this case, Siena only creates one table:

  • Table people_long_auto_extended
Table people_long_auto_extended
id
firstName
lastName
city
n
dogName
boss
profileImage
stillImages
otherImages

Filtering inherited fields

With Siena, you can also choose the fields from superclass that you want to store in the table of subclass.
Naturally, the subclass in the Java scope will inherit all fields from superclass but with this filtering mechanism, some fields from superclass can be removed by Siena from mapping.

For this, use the annotation @InheritFilter(removedFields={})
the removedFields parameter is a list of strings containing the names of the fields to remove from superclass (or superclasses if your inheritance hierarchy is deeper than 1 level).

@InheritFilter code sample

@Table("people_long_auto_extended_filter")
@InheritFilter(removedFields={ "city", "n"})
public class PersonLongAutoIDExtendedFilter extends PersonLongAutoIDModel {

	@Max(100)
	public String dogName;
	
	@Column("boss") @Index("boss_index")
	public PersonLongAutoIDModel boss;
    
	@Filter("boss")
	public siena.Query<PersonLongAutoIDExtendedFilter> employees;
           
	@Embedded
	public Image profileImage;
    
	@Embedded
	public List<Image> otherImages;

	@Embedded
	public Map<String, Image> stillImages;
    
	@EmbeddedMap
	public static class Image {
		public String filename;
		public String title;
	}
    ...
}

In this case, fields city and n from superclass will be ignored by siena mapping.
So, the table people_long_auto_extended_filter would look like:

Table people_long_auto_extended_filter
id
firstName
lastName
dogName
boss
profileImage
stillImages
otherImages

The PersonLongAutoIDExtendedFilter instances in JAVA naturally have those city and n fields but when you retrieve a PersonLongAutoIDExtendedFilter from DB:

  • city will be null (as any Object field filtered)
  • n will be 0 (as any Number field filtered)