0

我对 JPA 继承有疑问。请参阅下面的我的实体。我有一个Person可以在 aHouse或 a中的 a Car,当然不能同时出现。两者都Car实现House接口PersonHoldable。我知道我不能将实体直接映射到接口。

这是我的模型:

@Entity
public class Person{
  private PersonHoldable personHoldable; // either a Car or a House

  // This does not work of course because it's an interface
  // This would be the way to link objects without taking JPA into consideration.
  @OneToOne 
  public PersonHoldable getPersonHoldable() {
    return this.personHoldable;
  }

  public void setPersonHoldable(PersonHoldable personHoldable) {
    this.personHoldable = personHoldable;
  }
}

@Entity
public class Car implements PersonHoldable{}

@Entity
public class House implements PersonHoldable{}

public interface PersonHoldable{}

考虑到以下几点,我如何在 JPA 中正确映射它?

  1. 我尝试@MappedSuperclassPersonHoldable. 虽然它适用于这个特定的设置,但问题在于CarHouse实际上实现了更多的接口。它们也映射到其他实体。
  2. ThePerson可以有一个所有可能的属性PersonHoldable,所以在这种情况下它可以有一个getCar()andgetHouse()属性。这对我来说似乎不是很灵活。如果我要添加一个Bike实现,PersonHoldable我将不得不改变我的Person班级。
  3. PersonHoldable我可以反过来映射,因此仅在实现方面具有 OneToOne 关系。这意味着getPerson()PersonHoldable. 但是从一个Person角度来看,PersonHoldable它与什么相关联并不容易。
  4. 我正在使用默认的 JPA,所以如果可能的话,没有 Hibernate 特定的标签。

如果默认 JPA 无法做到这一点,那么在这种情况下最佳实践是什么?

4

1 回答 1

1

您的第二点的一个细微变化是使 Person 具有继承类型并实现 CarPerson 和 HousePerson(以及后来的 BikePerson),其全部目的是定义与特定 PersonH​​older 实现的特定连接关系。这使关系保持完整,并且更容易从 Person 端查询。

@Inheritance(strategy = JOINED)
@DiscriminatorColumn(name="holdableType", discriminatorType=CHAR, length=1)
@Entity
public class Person {
    // common fields
}

@Entity
@DiscriminatorValue("C")
public class CarPerson extends Person {
    @OneToOne
    private Car car;
}

@Entity
@DiscriminatorValue("H")
public class HousePerson extends Person {
    @OneToOne
    private House house;
}
于 2013-06-04T09:32:25.347 回答