2013-08-12 75 views
2

我有一個問題,我的Hibernate架構:@OneToOne或@ManyToOne引用了未知的實體:y.Person - 繼承問題

我有一個MappedSuperClass人,在員工和客戶。

--> Person.class 
@MappedSuperclass 
@Audited 
public class Person extends PersistentObject { 

    @Column(name="TITLE") 
    @Enumerated(EnumType.STRING) 
    private Title title; 

    @Column(name="FIRST_NAME") 
    private String fname  = null; 

    @Column(name="LAST_NAME") 
    private String lname  = null; 

--> Employee.class 
@Entity 
@Table(name="TBL_EMPLOYEE") 
@Audited 
public class Employee extends Person { 

--> Customer.class 
@Entity 
@Table(name="TBL_CUSTOMER") 
@Audited 
public class Customer extends Person { 

這個效果很好,但現在我的問題:我已經延長「人」與項目的列表,如地址/聯繫信息/等,並使用一個表的相同類型的所有項目(所有地址)。

當添加地址只有客戶,這是沒有問題:

--> Customer.java 
@OneToMany(cascade = {CascadeType.ALL}, mappedBy="customer") 
@LazyCollection(LazyCollectionOption.FALSE) 
private List<Address> addresses = null; 

--> Address.java 
@Entity 
@Table(name="TBL_ADDRESSES") 
@Audited 
public class Address extends PersistentObject { 
    @ManyToOne(fetch=FetchType.LAZY) 
    @JoinColumn(name="CUSTOMER_ID") 
    private Customer customer; 

現在我想將地址擴展到員工也。我想,我可以使用的超類型保存地址,但是這似乎並沒有工作的權利:

--> Person.java 
@OneToMany(cascade = {CascadeType.ALL}, mappedBy="person") 
@LazyCollection(LazyCollectionOption.FALSE) 
private List<Address> addresses = null; 

--> Address.java 
@Entity 
@Table(name="TBL_ADDRESSES") 
@Audited 
public class Address extends PersistentObject { 
    @ManyToOne(fetch=FetchType.LAZY) 
    @JoinColumn(name="PERSON_ID") 
    private Person person; 

運行時,我得到以下錯誤:@OneToOne or @ManyToOne on at.test.Address.person references an unknown entity: at.test.Person

有沒有可能性兩個實體都使用同一張表作爲他們的地址嗎? ID不會衝突,因爲員工和客戶共享相同的順序。或者我應該以另一種方式設計這個問題?

非常感謝您提前和最好的問候!

+0

HAVA看看這個博客http://viralpatel.net/blogs/hibernate-inheritance-table-per-concrete-class-annotation-xml-mapping/。 – Flo

+0

非常感謝這個鏈接,我意識到「每個子類一個表」範例就是我所期待的! – user2674457

回答

0

從Flo的鏈接引用它,我意識到,正確的範例用於我的問題是「每個子類一個表」之一。謝謝您的幫助!

2

你必須聲明你的超類的@Entity,而不是@MappedSuperclass和單個表inheritancet策略,這樣你就可以在你的多對一的關係

@Entity 
@Table(name="PERSON") 
@Inheritance(strategy=InheritanceType.SINGLE_TABLE) 
@DiscriminatorColumn(name="discriminator",discriminatorType=DiscriminatorType.STRING) 
@DiscriminatorValue(value="P") 
public abstract class Person { 

    @Id 
    @GeneratedValue 
    @Column(name = "PERSON_ID") 
    private Long personId; 

    private String firstname; 

    private String lastname; 

    @OneToMany(cascade = {CascadeType.ALL}, mappedBy="customer") 
    @LazyCollection(LazyCollectionOption.FALSE) 
    private List<Address> addresses = null; 
} 

@Entity 
@Table(name="PERSON") 
@DiscriminatorValue("E") 
public class Employee extends Person { 

} 

@Entity 
@Table(name="PERSON") 
@DiscriminatorValue("C") 
public class Customer extends Person { 

} 

@Entity 
@Table(name="TBL_ADDRESSES") 
@Audited 
public class Address extends PersistentObject { 
    @ManyToOne(fetch=FetchType.LAZY) 
    @JoinColumn(name="PERSON_ID") 
    private Person person; 
} 
+0

感謝您的第一個提示。但是如果我想爲客戶/員工添加許多不同的屬性呢?這些存儲在哪裏?在共同的桌子?在我看來,最好保留客戶/員工表並在地址中添加一個判別器。我試過這個,但它不能按預期工作。儘管如此,感謝您的意見! – user2674457

+0

我有類似的問題。你願意幫助我嗎?這裏是鏈接:http://stackoverflow.com/questions/25252541/generatedvalue-for-a-java-abstract-superclass-over-mysql – CodeMed

0

在Address類中,您必須將參數insertable和updatable設置爲false。這實際上是有道理的,因爲如果你不這樣做。 JPA允許你創建一些「Person」(可能未映射)對象,將它分配給地址,然後與地址對象一起保存。試着用下面的代碼:

@Entity 
@Table(name="PERSON") 
@Inheritance(strategy=InheritanceType.SINGLE_TABLE) 
@DiscriminatorColumn(name="discriminator",discriminatorType=DiscriminatorType.STRING) 
public abstract class Person { 

    @Id 
    @GeneratedValue 
    @Column(name = "PERSON_ID") 
    private Long personId; 

    private String firstname; 

    private String lastname; 

    @OneToMany(cascade = {CascadeType.ALL}, mappedBy="customer") 
    @LazyCollection(LazyCollectionOption.FALSE) 
    private List<Address> addresses = null; 
} 

@Entity 
@Table(name="PERSON") 
@DiscriminatorValue("E") 
public class Employee extends Person { 

//some fields 
} 

@Entity 
@Table(name="PERSON") 
@DiscriminatorValue("C") 
public class Customer extends Person { 
    //some fields 
} 

@Entity 
@Table(name="TBL_ADDRESSES") 
@Audited 
public class Address extends PersistentObject { 
    @ManyToOne(fetch=FetchType.LAZY) 
    @JoinColumn(name="PERSON_ID", insertable = false, updatable = false) 
    private Person person; 
} 
相關問題