2012-08-30 18 views
10

Actualmente tengo un modelo de estructura de la siguiente manera:Symfony2/Doctrina asignada superclase en la mitad de la herencia de tablas de clase

/** 
* @ORM\Entity 
* @ORM\InheritanceType("JOINED") 
* @ORM\DiscriminatorColumn(name="related_type", type="string") 
* @ORM\DiscriminatorMap({"type_one"="TypeOne", "type_two"="TypeTwo"}) 
*/ 
abstract class BaseEntity { 

    ... (all the usual stuff, IDs, etc) 

    /** 
    * @ORM\OneToMany(targetEntity="Comment", mappedBy="baseEntity") 
    */ 
    private $comments; 
} 

/** 
* @ORM\Entity 
*/ 
class TypeOne extends BaseEntity { 
    /** 
    * @ORM\Column(type="string") 
    */ 
    private $name; 

    /** 
    * @ORM\Column(type="string") 
    */ 
    private $description; 
} 

/** 
* @ORM\Entity 
*/ 
class TypeTwo extends BaseEntity { 
    /** 
    * @ORM\Column(type="string") 
    */ 
    private $name; 

    /** 
    * @ORM\Column(type="string") 
    */ 
    private $description; 
} 

/** 
* @ORM\Entity 
*/ 
class Comment { 

    ... (all the usual stuff, IDs, etc) 

    /** 
    * @ORM\ManyToOne(targetEntity="BaseEntity", inversedBy="comments") 
    */ 
    private $baseEntity; 
} 

La idea aquí es ser capaz de atar un comentario a cualquiera de las otras mesas. Todo parece estar funcionando bien hasta ahora (concedido, todavía estoy explorando opciones de diseño, así que podría haber una mejor manera de hacerlo ...), pero lo único que noté es que las subclases tienen algunos campos comunes que me gustaría pasar a una clase común para padres. No quiero moverlos a BaseEntity ya que habrá otros objetos que son hijos de BaseEntity, pero que no tendrán esos campos.

He pensado en la creación de una clase padre MappedSuperclass en el medio, así:

/** 
* @ORM\MappedSuperclass 
*/ 
abstract class Common extends BaseEntity { 
    /** 
    * @ORM\Column(type="string") 
    */ 
    private $name; 

    /** 
    * @ORM\Column(type="string") 
    */ 
    private $description;  
} 

/** 
* @ORM\Entity 
*/ 
class TypeOne extends Common {} 

/** 
* @ORM\Entity 
*/ 
class TypeTwo extends Common {} 

Pensé que esto iba a funcionar, pero el generador de esquema de base de la doctrina se queja de que no puedo tener un mapeo OneToMany en una MappedSuperclass. No esperaba que esto fuera un problema, ya que el mapeo de OneToMany aún se encuentra entre la raíz BaseEntity y la tabla de comentarios. ¿Hay alguna estructura diferente que debería utilizar o alguna otra forma de hacer que estos campos sean comunes sin agregarlos en BaseEntity?

Respuesta

14

De los Documentos:

Un mapeado superclase es una clase abstracta o concreta que proporciona información de estado entidad y asignación persistente de sus subclases, pero que no es en sí una entidad es. Típicamente, el propósito de dicha superclase mapeada es definir información de estado y mapeo que es común a múltiples clases de entidad.

Dicho esto, ¿cómo se puede asociar una entidad con una que no lo es?

Más de la documentación:

Una superclase asignada no puede ser una entidad, que no es en consultas capaces y relaciones persistentes definidos por una superclase asignada debe ser unidireccional (con una propietaria solo lado). Esto significa que las asociaciones One-To-Many no son posibles en absoluto en una superclase mapeada. Además, las asociaciones Muchos a Muchos solo son posibles si la superclase asignada solo se usa en exactamente una entidad en este momento. Para soporte adicional de herencia, se deben usar las características de herencia de tabla única o combinadas .

Fuente: http://docs.doctrine-project.org/projects/doctrine-orm/en/latest/reference/inheritance-mapping.html


actualización

Debido a que su MappedSuperClass extiende BaseEntity también hereda las asociaciones del BaseEntity, como si fuera su propio. Entonces efectivamente tienes un OneToMany en MappedSuperClass.

Para evitarlo, bien, necesitaría modificar/ampliar la doctrina para que funcione de la manera que desee.

En cuanto a la funcionalidad nativa va usted tiene dos opciones:

Herencia de tablas Clase Usted clase común y la representación DB resultante tendría los campos comunes y clases hijas ahora sólo tienen los campos específicos para ellos mismos . Desafortunadamente, esto puede ser una tergiversación de sus datos si simplemente está tratando de agrupar los campos comunes con el fin de agruparlos.

poner en común una Entidad Parece ser que todo un Super clase mapeada es es una entidad que no está representado en la DB. Entonces, haz una Entidad común en su lugar. La desventaja es que terminará con una tabla DB, pero podría simplemente eliminar eso.

Le recomiendo que eche un segundo vistazo a sus datos y asegúrese de que solo está agrupando campos si son comunes tanto en nombre como en propósito. Por ejemplo, un ComputerBox, un ShoeBox, un hombre y una mujer pueden tener la propiedad de "altura", pero en ese caso no recomendaría tener una clase común con una propiedad de "altura" de la que todos hereden. En cambio, tendría un cuadro con campos comunes para ComputerBox y ShoeBox y tendría una persona con campos comunes para el hombre y la mujer. En esa situación, la tabla de herencia de clase o una sola tabla, si lo prefiere, funcionaría perfectamente.

Si sus datos siguen ese ejemplo, vaya con Single Table o Class Table Herencia. De lo contrario, podría aconsejar no agrupar los campos.

+0

Entiendo que las asociaciones de uno a muchos no son posibles en una superclase mapeada ... sin embargo, mi situación es un poco diferente. Mi estructura propuesta es BaseEntity (una entidad real) -> MappedSuperclass -> GrandchildrenEntities (también entidades). La asociación de uno a muchos se encuentra entre BaseEntity y otra Entity. Por lo tanto, técnicamente, la asociación no es una MappedSuperclass ya que la superclase mapeada es un elemento secundario de BaseEntity y no contiene la asociación de uno a muchos. – cdwhatcott

+0

ver mi respuesta actualizada – KTastrophy

+0

Gracias por la actualización. Después de haber pasado algún tiempo trabajando en otras cosas y luego volviendo a este problema, creo que la mejor opción sería hacer una entidad 'común' como sugeriría. – cdwhatcott

Cuestiones relacionadas