inheritance relationship is appropriate only for the object model and a fashion does not exist in the relational model. Therefore, approaches have been developed to represent the relational models of inheritance:
- one table per concrete class (Single table per Concrete Class)
- one table per class hierarchy (Single table per Class Hierarchy),
- join subclass (Joined Subclass).
JPA specification, using the @ Inheritance annotation
, enables the use of each of these three strategies represent inheritance. Example -
problem area for the purposes of this article will use the following data model: It is a simple hierarchy of classes, from which the abstract class
person is the parent class, and class OsobaPrawna
and OsobaFizyczna
inherit from it. One table per class concrete (Single table per Concrete Class)
Acc. this strategy would present the relational model is as follows: This approach provides that for each class of concrete will fall a table in the relational model. In our case we will set up tables for classes and OsobaPrawna
OsobaFizyczna
. At the same time, these tables will also include a column representing the inherited attributes. Here it should be noted that it is not possible to override the mapping of inherited attributes - will not work @ AttributeOverride endorsement (s)
. class An
not explicitly mapped in the relational model. This feature makes the polymorphic associations (ie, a general reference to being
person, not a specific kind of people) are not possible, and polymorphic queries very difficult (in queries using the union, or dissected by a separate query for each subclasses). Below code snippets class definitions mapping: @ Entity
@ Inheritance (strategy = InheritanceType.TABLE_PER_CLASS) public abstract class Person {... } @ Entity
(name = "osoba_prawna") public class Person {OsobaPrawna extends ... }
@ Entity (name = "osoba_fizyczna") public class Person {OsobaFizyczna extends ... }full source in the form of a project can be downloaded maven'owego here.
One table per class hierarchy (Single table per Class Hierarchy)
Acc. this strategy would present the relational model is as follows: In this approach, a hierarchy of classes is only one table. In our case, this means that all classes (Person
, OsobaPrawna
, OsobaFizyczna
) will be represented by only one table. This table is in addition to the columns representing attributes of these classes, will have a column flag (discriminator) - os_typ
, which will determine which class is given a particular record. It is not necessary to define the class attribute representing discriminator'a, but once this is done, then the mapping of this attribute must be switched off the option of recording and updating of this value, since it can not be changed manually. The solution does not have the disadvantages associated with polymorphism, which had the previous approach. However, has another drawback in the ability to define constraints of columns (above all
not null
) specific to particular classes. For example, you can not enforce that the column mapping OsobaPrawna.regon
could not accept blank values, since this condition does not meet any record representing the object OsobaFizyczna
. Below code snippets from the mapping class definition: @
Entity (name = "person") @ Inheritance (strategy = InheritanceType.SINGLE_TABLE) @ DiscriminatorColumn (name = "os_typ") public abstract class Person {... } @ Entity
@ DiscriminatorValue (value = "IP") public class Person {OsobaPrawna extends ... } @ Entity
@ DiscriminatorValue (value = "OF") public class Person {OsobaFizyczna extends ... }full source in the form of a project can be downloaded maven'owego here. Merge
subclass (Joined Subclass)
Acc. this strategy would present the relational model is as follows: In this approach, each class (even abstract) in the relational model, its representation in the form of a table. This means that a particular object will be stored in the table in part an abstract class and partly in the table a specific class. In our example, the object attributes OsobaPrawna
will be stored in a table OsobaPrawna
as well as the inherited attributes in the table
Person. Being inheriting must have recourse to the entity from which it inherits. The role of the appeal may be common master key. And so the row in the table Klast
OsobaPrawna
will have a primary key equal in value to a key line in the table class Person
. This approach does not have the disadvantages of previous solutions. In addition, the relational model is characterized by a higher degree of standardization in relation to competitive solutions. What it may also be a disadvantage of this strategy, because a higher degree of standardization means that the data are scattered in more tables, which increases the complexity of queries and to some extent the time of their execution.
Below code snippets from the mapping class definition: @
Entity (name = "person") @ Inheritance (strategy = InheritanceType.JOINED) public abstract class Person {... } @ Entity
(name = "osoba_prawna") @ PrimaryKeyJoinColumn (name = "op_id") public class Person {OsobaPrawna extends ... } @ Entity
(name = "osoba_fizyczna") @ PrimaryKeyJoinColumn (name = "of_id") public class Person {OsobaFizyczna extends ... }Complete source as maven'owego project can be downloaded here .
Inheritance is not a class of entities
JPA specification provides for two ways of behavior in the case of inheritance from a non-class entities.first option - the base class is not annotated
@ MappedSuperclass
. In this case, the inherited attributes are fleeting and will not be stored in the database after the operation the fixation object. second option - the base class is marked with a note
@ MappedSuperclass
. Then the attributes are inherited according to fixed. mappings defined in this base class. At the same time it is possible to overwrite these mappings by using the annotation @ AttributeOverride (s)
. In my opinion mapped class parents are an interesting option and can be used even in the definition of base class of all entities that will contain the attributes that contain information about changes made to the entity.
Below is an example of the mapped class:
MappedSuperclass public class @ {private String EncjaAudytowalna uzytkownikModyfikujacy; private Date dataModyfikacji; @ Column (name = "audyt_uzytkownik") public String getUzytkownikModyfikujacy () {return uzytkownikModyfikujacy;} public void setUzytkownikModyfikujacy (String uzytkownikModyfikujacy) {
this.uzytkownikModyfikujacy = uzytkownikModyfikujacy;
}
@Column(name="audyt_data")
@Temporal(value=TemporalType.TIMESTAMP)
public Date getDataModyfikacji() {
return dataModyfikacji;
}
public void setDataModyfikacji(Date dataModyfikacji) {
this.dataModyfikacji = dataModyfikacji;
}
}
@Entity
@AttributeOverride(name="uzytkownikModyfikujacy", column=@Column(name="uz_au_um"))
public class Uzytkownik extends EncjaAudytowalna {
private Long id;
private String name;
@Id
@GeneratedValue(strategy=GenerationType.AUTO)
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;} @ Column (name = "name") public String getName () {return name;} public void setName (String name) {this.name = name;}}
Resources
Hibernate Annotations - 2.2.4. Mapping inheritanceJPA specification
0 comments:
Post a Comment