I am using Doctrine PHP ORM 2.0.
What I would like to implement, is the following class hierarchy. (Please note that the following code fragment will fail to execute, as it is neither syntactically correct PHP, nor correct usage of Doctrine annotations.)
@MappedSuperclass
abstract class Location {}
@Entity
class GeoId {
@Column(type = "float") $latitude;
@Column(type = "float") $longitude;
// this is the part that my question concerns
@???
$location; // any subclass of location can go here
}
Now, for the subclasses of Location we could take City
, State
and Country
, for example. Or Adress
, if we want to be very specific. For a little more information on this class hierarchy:
class Adress { $parent; /* of type City, ... some other attributes */ }
class City { $parent; /* of type State */ }
class State { $parent; /* of type Countr开发者_开发问答y */ }
class Country {}
(The above hierarchy would make my answer lean towards a Table-per-Class solution.)
Questions:
- Is it possible to have a polymorphic attribute in an entity, and if so, how do I implement it?
- Which what inheritance strategy could I implement the Location class hierarchy (as seen below), and which strategies are preferred (i.e. MappedSuperclass, Single-Table or Class-Table inheritance)?
Is it possible to have a polymorphic attribute in an entity, and if so, how do I implement it?
Yes, Doctrine 2 supports three different types of inheritance: MappedSuperclass, Single Table and Class Table... as you know. The Doctrine Reference explains how to implement them.
Here is a good article you can read on mapping object inheritance: Mapping Objects to Relational Databases: O/R Mapping In Detail
In this case you'd need Single- or Class-Table-Inheritance. Because you want to query for the root (Location) you should better use Single Table Inheritance for performance reasons.
Yes, Doctrine 2 will do polymorphic associations. There issues with bi-directional associations using mappedBy
and inversedBy
, but the simple case works fine.
/** @Entity */
class GeoId {
/** @Column(type = "float") */
private $latitude;
/** @Column(type = "float") */
private $longitude;
/** @OneToOne(targetEntity="Location") */
private $location;
}
精彩评论