Model inheritance
PlayMorphia allows you easily persist you model entities across class hierarchies. There are two types of inheritance mode usually:
- Abstract parent class
- Concrete parent class
Whatever mode you use your parent class must directly or indirectly extend PlayMorphia’s play.modules.morphia.Model
class.
Abstract parent class
You cannot put @Entity
annotation to an abstract class, thus you must put @Entity
to the concrete child class when your parent class is abstract:
public abstract class Person extends Model {
public String fName;
public String lName;
}
@Entity
public class Student extends Person {
public String major;
public String grade;
}
@Entity
public class Teacher extends Person {
pubilc List<String> courses;
}
Concrete parent class
You can choose to annotate @Entity
to concrete parent class or not. Here is the rule:
if you have db entity corresponding to a class then you MUST annotate it with @Entity
So if you save entities of the the parent class, you must annotate it with the @Entity
, otherwise you should not to save the boot-up time of your application.
About @play.modules.morphia.Model.NoId annotation
Usually if you concrete parent class is annotated with @Entity
, the ID field is added to the parent class and it will not be added to the child class during code enhancement. However in rare time when Play load child class before parent class, the ID field will be added to the child class and later when parent class loaded it’s added again, and hence we got the duplicate field found problem as described in this thread.
It shouldn’t happen theoretically, but if you found it in your environment, the @play.modules.morphia.Model.NoId annotation
annotation could save your life. Just put it to your children class and PlayMorphia’s code enhancer will not add ID to your child class anyway.
About noClassnameStored()
By default Morphia will save the class name of the entity into the database for the sake of inheritance. If you are sure that you don’t have instances of multiple classes persisted into the same collection, then you could use noClassnameStored
argument in the @Entity
annotation:
@Entity(noClassnameStored = true)
public class TrackInfo extends Model {
public String action;
public long timestamp;
...
}