2012-03-12 27 views
42

Estoy usando Play Framework 1.2.4 con PostgreSQL y JPA. Me gustaría tener una jerarquía de modelos y ver que hay algunas alternativas para hacer esto.JPA: implementación de la jerarquía del modelo - @MappedSuperclass vs. @Intermitance

Tengo una clase base (que es abstracta) y dos clases concretas que extienden esta clase base. No quiero persistir en esta clase base mientras quiero tener clases concretas. En la clase base, tengo otras clases de modelo como propiedades, en otras palabras, tengo relaciones @ManyToOne en mi clase base.

Mi pregunta es ¿cuál es la mejor manera de implementar esto? ¿Usando @MappedSuperclass o @Inheritance con la estrategia TABLE_PER_CLASS? Estoy un poco confundido ya que parecen virtualmente equivalente.

También tengo algunas preocupaciones sobre las consultas y los problemas de rendimiento que podría enfrentar en el futuro.

+1

He cambiado '@ Inheritence' a' @ Inheritance' porque supuse que era un error tipográfico. –

Respuesta

96

MappedSuperClass se debe utilizar para heredar propiedades, asociaciones y métodos.

La herencia de la entidad se debe usar cuando se tiene una entidad y varias subentidades.

Puede decir si necesita una u otra respondiendo estas preguntas: ¿hay alguna otra entidad en el modelo que pueda tener una asociación con la clase base?

En caso afirmativo, la clase base es en realidad una entidad, y debe usar la herencia de la entidad. Si no, entonces la clase base es de hecho una clase que contiene atributos y métodos que son comunes a varias entidades no relacionadas, y usted debe usar una superclase mapeada.

Por ejemplo:

  • Puede tener varios tipos de mensajes: mensajes SMS, mensajes de correo electrónico o mensajes telefónicos. Y una persona tiene una lista de mensajes. También puede tener un recordatorio vinculado a un mensaje, independientemente del tipo de mensaje. En este caso, Message es claramente una entidad, y la herencia de la entidad debe ser utilizada.
  • Todos los objetos de su dominio pueden tener una fecha de creación, fecha de modificación e ID, por lo que podrían hacer que hereden de una clase base de AbstractDomainObject. Pero ninguna entidad tendrá una asociación con un AbstractDomainObject. Siempre será una asociación a una entidad más específica: Cliente, Empresa, lo que sea. En este caso, tiene sentido usar MappedSuperClass.
+0

Muchas gracias por su respuesta. Ahora tengo claro que si necesito persistir o usar la clase base como entidad, debería usar la herencia de la entidad. Me pregunto si hay un problema con el rendimiento o la restricción de las consultas, especialmente el uso de relaciones de objetos heredados. – huzeyfe

+0

Todo depende del tipo de herencia que elija y de la estrategia de herencia. –

+0

En mi caso (ya que no quiero persistir en la clase base) MappedSuperClass parece más adecuado. Entonces, en términos de rendimiento y restricciones, ¿necesito estar al tanto de algunos problemas? – huzeyfe

2

Como expliqué en this article, @MappedSupperclass es diferente que el @Inheritance anotación.

@MappedSuperclass indica al proveedor de JPA que incluya las propiedades persistentes de la clase base como si hubieran sido declaradas por la clase secundaria extendiendo la superclase anotada con @MappedSuperclass.

Sin embargo, la herencia solo es visible en el mundo OOP, ya que, desde una perspectiva de base de datos, no hay indicación de la clase base. Solo la entidad de clase hija tendrá una tabla asignada asociada.

La anotación @Inheritance pretende materializar el modelo de herencia de OOP en la estructura de la tabla de la base de datos. Además, puede consultar una clase base anotada con @Inheritance, pero no puede hacer eso para una clase base anotada con @MappedSuperclass.

Ahora, la razón por la que desea utilizar el @Inheritance JPA annotation is to implement behavior-driven patterns like the Strategy Pattern.

Por otro lado, @MappedSuperclass es solo una forma de reutilizar las propiedades básicas, asociaciones e incluso la entidad @Id utilizando una clase base común. Sin embargo, puede lograr casi el mismo objetivo utilizando un tipo @Embeddable. La única diferencia importante es que no puede reutilizar una definición @Id con @Embeddable, pero puede hacerlo con @MappedSuperclass.

Cuestiones relacionadas