2010-11-24 28 views
25

Veri modelim, İşletme veya Kişi gibi tüzel kişileri temsil eder. Her ikisi de vergi ödeyen varlıklardır ve her ikisinde de bir TaxID, bir telefon numarası koleksiyonu ve bir posta adresi koleksiyonu vardır.Soyut süper sınıfların Hibernate (JPA) devralma eşlemesi

Soyut sınıfları genişleten iki beton sınıflı bir Java modelim var. Soyut sınıf, hem somut sınıflar için ortak olan özelliklere ve koleksiyonlara sahiptir.

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 

böyle sınıfları ile, bir MySQL veritabanı üzerinde hazırda JPA Ek Açıklamalar kullanıyorum:

@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; 
} 

sorun Phone ve Address nesneler bakmanız gerekir ki onların AbstractLegalEntity olan sahip. Bu oldukça yaygın bir Java miras senaryo olacak gibi

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

görünüyor, bu yüzden hazırda bunu destekleyeceğini umuyoruz: Hazırda şikayet ediyor. Ben, artık @MappedSuperclass kullanarak Hibernate forum question dayalı AbstractLegalEntity için eşleme değiştirmeyi denedim:

@Entity 
@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS) 

Ancak, şimdi aşağıdaki hatayı alıyorum. Bu devralma eşleme türünü okurken, SEQUENCE değil IDENTITY kullanmam gerekiyor ve MySQL SIRALAMA'yı desteklemiyor gibi görünüyor.

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

Aşağıdaki eşleştirmeyi kullandığımda işlerimi geliştirmek için daha fazla ilerleme yapıyorum.

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

Bu yola devam etmem gerektiğini düşünüyorum. Benim endişem, hiç bir zaman bir SoyutLegalEntity örneğini hiç istemediğimde onu bir @Entity olarak eşleştirdiğim. Bunun doğru bir yaklaşım olup olmadığını bilmek isterim. Bu durum için almam gereken doğru yaklaşım nedir?

+1

Hazırda bekletme, hazırda bekletme ek açıklamaları için JPA ek açıklamaları kullanmıyorsunuz. Bu önemli bir ayrım. –

+0

@ S. P.Floyd - ah evet, bu doğru. Sorumu çözdüğün için teşekkürler. – Tauren

cevap

37

Kullanım:

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

Ardından veritabanında Eğer AbstractLegalEntity sınıfını genişleten sınıflar için AbstractLegalEntity ve tablolar için bir tablo olacaktır. Özet ise, AbstractLegalEntity örneklerine sahip olmazsınız. Polimorfizm burada kullanılabilir.

kullandığınızda: Bu veritabanı sadece bir masa ConcretePersonEntity içinde ancak her iki sınıflardan sütunlarla oluşturur

@MappedSuperclass 
AbstractLegalEntity 

@Entity 
ConcretePersonEntity extends AbstractLegalEntity 

.

+0

teşekkürler, bu durumları açıklığa kavuşturmaya yardımcı olur. Aynı zamanda SINGLE_TABLE'ı da kullanabildim, bu da daha az birleşme istediğimde ve sınıf hiyerarşisinde tonlarca alan olmadığında anlam ifade ediyor. – Tauren

+0

+1 Benzer bir sorunum var. Bana yardım etmek ister misin? Özellikle, DDL ve varlık tanımları konusunda yardıma ihtiyacım var. Kodumu gönderdim. İşte bağlantı: http://stackoverflow.com/questions/25252541/generatedvalue-for-a-java-abstract-superclass-over-mysql – CodeMed

+0

harika. işe yarıyor – emoleumassi

1

AbstractLegalEntity için @Entity ek açıklaması ekleyin. AbstractLegalEntity örneği asla bulunmayacaktır - hazırda bekleme alanına göre uygun genişletme örnekleri - ConcreteBusinessEntity veya ConcretePersonEntity yüklenir.

+4

A sınıfı, CAN @ "Entity" ve "MappedSuperClass" olarak işaretlenemez! – Stephan

1

AbstracLegalEntity ürününü @Entity olarak bildirmeniz gerekir. @Entity ek açıklamasında bile, sınıfınız soyut kalır. Sonuç olarak, yalnızca somut alt sınıfların örneğine sahip olacaksınız.

İlgili konular