3

我的 Hibernate 架构有问题:

我有一个 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;

现在我也想将地址扩展到员工。我想,我可以使用 Supertype 来保存地址,但这似乎不起作用:

--> 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 不会冲突,因为 Employee 和 Customer 共享相同的序列。或者我应该以另一种方式设计这个问题?

非常感谢您提前和最好的问候!

4

3 回答 3

4

您必须将您的超类声明为 @Entity 而不是 @MappedSuperClass 和单表继承策略,因此您可以在 ManyToOne 关系中引用它

@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;
}
于 2013-08-12T10:56:01.590 回答
0

从 Flo 的链接中,我意识到解决我的问题的正确范例是“每个子类一个表”。谢谢您的帮助!

于 2013-08-20T10:40:13.597 回答
0

在 Address 类上,您必须将可插入和可更新的参数设置为 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;
}
于 2016-06-15T05:09:35.003 回答