2010-11-24 14 views
25

Mi modelo de datos representa entidades legales, como una empresa o una persona. Ambas son entidades que pagan impuestos, y ambas tienen un TaxID, una colección de números de teléfono y una colección de direcciones postales.Hibernate (APP) mapeo herencia de clases abstractas súper

que tienen un modelo de Java con dos clases concretas que se extienden una clase abstracta. La clase abstracta tiene propiedades y colecciones que son comunes a ambas clases concretas.

AbstractLegalEntity  ConcreteBusinessEntity ConcretePersonEntity 
-------------------  ---------------------- -------------------- 
Set<Phone> phones   String name    String first 
Set<Address> addresses  BusinessType type   String last 
String taxId           String middle 

Address     Phone 
-------     ----- 
AbsractLegalEntity owner AbstractLegalEntity owner 
String street1    String number 
String street2   
String city 
String state 
String zip 

estoy usando Hibernate anotaciones JPA en una base de datos MySQL , con las clases de la siguiente manera:

@MappedSuperclass 
public abstract class AbstractLegalEntity { 
    private Long id; // Getter annotated with @Id @Generated 
    private Set<Phone> phones = new HashSet<Phone>(); // @OneToMany 
    private Set<Address> address = new HashSet<Address>(); // @OneToMany 
    private String taxId; 
} 

@Entity 
public class ConcretePersonEntity extends AbstractLegalEntity { 
    private String first; 
    private String last; 
    private String middle; 
} 

@Entity 
public class Phone { 
    private AbstractLegalEntity owner; // Getter annotated @ManyToOne @JoinColumn 
    private Long id; 
    private String number; 
} 

El problema es que Phone y Address objetos necesitan para hacer referencia a su propietario, que es un AbstractLegalEntity. Hibernate se queja:

@OneToOne or @ManyToOne on Phone references an unknown 
entity: AbstractLegalEntity 

Parece que este sería un escenario bastante común herencia de Java, así que espero que Hibernate lo apoyaría. He intentado cambiar la asignación para AbstractLegalEntity basado en un Hibernate forum question, que ya no utilizan @MappedSuperclass:

@Entity 
@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS) 

Sin embargo, ahora me sale el siguiente error. Al leer en este tipo de mapeo de herencia, parece que tengo que usar SEQUENCE not IDENTITY, y MySQL no admite SEQUENCE.

Cannot use identity column key generation with <union-subclass> 
mapping for: ConcreteBusinessEntity 

Estoy haciendo más progresos para que las cosas funcionen cuando utilizo la siguiente asignación.

@Entity 
@Inheritance(strategy = InheritanceType.SINGLE_TABLE) 
@DiscriminatorColumn(
     name="entitytype", 
     discriminatorType=DiscriminatorType.STRING 
) 

Estoy pensando que debería continuar por este camino. Mi preocupación es que lo estoy mapeando como @Entity cuando realmente no quiero que exista nunca una instancia de AbstractLegalEntity. Me gustaría saber si este es el enfoque correcto. ¿Cuál es el enfoque correcto que debería tomar para esta situación?

+1

está utilizando anotaciones JPA en hibernación, no en anotaciones de hibernación. Esa es una distinción importante. –

+0

@ S.P.Floyd - ah sí, eso es correcto. gracias por corregirlo en mi pregunta. – Tauren

Respuesta

37

Uso:

@Entity 
@Inheritance(strategy = InheritanceType.JOINED) 
AbstractLegalEntity 

Luego, en la base de datos tendrá una mesa para AbstractLegalEntity y mesas para las clases que se extiende clase AbstractLegalEntity. No tendrá instancias de AbstractLegalEntity si es abstracto. El polimorfismo se puede usar aquí.

Cuando se utilice:

@MappedSuperclass 
AbstractLegalEntity 

@Entity 
ConcretePersonEntity extends AbstractLegalEntity 

Se crea la base de datos sólo una ConcretePersonEntity mesa, pero con columnas de ambas clases.

+0

gracias, esto ayuda a aclarar las cosas. también pude usar SINGLE_TABLE, lo cual tiene sentido cuando quiero menos combinaciones y no hay muchos campos en la jerarquía de clases. – Tauren

+0

+1 Tengo un problema similar. ¿Estás dispuesto a ayudarme con eso? En particular, necesito ayuda con las definiciones DDL y de entidad. Publiqué mi código. Aquí está el enlace: http://stackoverflow.com/questions/25252541/generatedvalue-for-a-java-abstract-superclass-over-mysql – CodeMed

+0

genial. esta funcionando – emoleumassi

1

Añadir @Entity anotación a AbstractLegalEntity. La instancia de AbstractLegalEntity nunca existirá: hibernate cargará las instancias de extensión apropiadas: ConcreteBusinessEntity o ConcretePersonEntity según el campo Id.

+4

¡Una clase NO PUEDE estar marcada como '@ Entity' y' @ MappedSuperClass'! – Stephan

1

tienes que declarar AbstracLegalEntity como @Entity. Incluso con la anotación @Entity, su clase permanece abstracta. en consecuencia, solo tendrá instancias de subclases concretas.