2013-08-12 78 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; 
} 
相关问题